Title: [223843] trunk
Revision
223843
Author
[email protected]
Date
2017-10-23 10:51:08 -0700 (Mon, 23 Oct 2017)

Log Message

Implement drawImage(ImageBitmap) on 2d canvas
https://bugs.webkit.org/show_bug.cgi?id=178653
<rdar://problem/35104360>

Reviewed by Antoine Quint.

LayoutTests/imported/w3c:

Update expected results now that drawImage is implemented.

* web-platform-tests/2dcontext/imagebitmap/createImageBitmap-drawImage-expected.txt:

Source/WebCore:

Implement CanvasRenderingContext2D::drawImage with ImageBitmap.
It's probably not going to be a very common operation, but
it importantly allows us to test the ImageBitmap creation
code.

Test: http/wpt/2dcontext/imagebitmap/drawImage-ImageBitmap.html

* html/ImageBitmap.cpp:
(WebCore::taintsOrigin): New helper function to determine if a
CachedImage would provide a clean origin.
(WebCore::ImageBitmap::createPromise): Set the flag that records
if this ImageBitmap has a clean origin.
* html/ImageBitmap.h:
(WebCore::ImageBitmap::buffer): Exposes the ImageBuffer backing
store, allowing access to the data for drawing.
(WebCore::ImageBitmap::originClean const): Is this ImageBitmap
going to taint a destination.
* html/canvas/CanvasRenderingContext.cpp:
(WebCore::CanvasRenderingContext::wouldTaintOrigin): Implement
the ImageBitmap version of this template function.
* html/canvas/CanvasRenderingContext.h:
* html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::drawImage): Implement the
actual drawing of an ImageBitmap.

LayoutTests:

Add a new test that exercises drawImage(ImageBitmap)
that will be contributed back to Web Platform Tests.

* http/wpt/2dcontext/imagebitmap/common.js: Copied (mostly) from WPT.
(create9x9CanvasWith2dContext): New helper function to create a canvas
and provide a rendering context.
* http/wpt/2dcontext/imagebitmap/drawImage-ImageBitmap-expected.txt: Added.
* http/wpt/2dcontext/imagebitmap/drawImage-ImageBitmap.html: Added.
* http/wpt/2dcontext/imagebitmap/target-blue-dot.png: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (223842 => 223843)


--- trunk/LayoutTests/ChangeLog	2017-10-23 17:49:22 UTC (rev 223842)
+++ trunk/LayoutTests/ChangeLog	2017-10-23 17:51:08 UTC (rev 223843)
@@ -1,3 +1,21 @@
+2017-10-22  Dean Jackson  <[email protected]>
+
+        Implement drawImage(ImageBitmap) on 2d canvas
+        https://bugs.webkit.org/show_bug.cgi?id=178653
+        <rdar://problem/35104360>
+
+        Reviewed by Antoine Quint.
+
+        Add a new test that exercises drawImage(ImageBitmap)
+        that will be contributed back to Web Platform Tests.
+
+        * http/wpt/2dcontext/imagebitmap/common.js: Copied (mostly) from WPT.
+        (create9x9CanvasWith2dContext): New helper function to create a canvas
+        and provide a rendering context.
+        * http/wpt/2dcontext/imagebitmap/drawImage-ImageBitmap-expected.txt: Added.
+        * http/wpt/2dcontext/imagebitmap/drawImage-ImageBitmap.html: Added.
+        * http/wpt/2dcontext/imagebitmap/target-blue-dot.png: Added.
+
 2017-10-23  Daniel Bates  <[email protected]>
 
         Add tests to ensure spelling error dots are drawn in the correct place for overlapping lines

Added: trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/common.js (0 => 223843)


--- trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/common.js	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/common.js	2017-10-23 17:51:08 UTC (rev 223843)
@@ -0,0 +1,66 @@
+function testCanvasDisplayingPattern(canvas)
+{
+    var tolerance = 5; // for creating ImageBitmap from a video, the tolerance needs to be high
+    _assertPixelApprox(canvas, 5,5, 255,0,0,255, "5,5", "255,0,0,255", tolerance);
+    _assertPixelApprox(canvas, 15,5, 0,255,0,255, "15,5", "0,255,0,255", tolerance);
+    _assertPixelApprox(canvas, 5,15, 0,0,255,255, "5,15", "0,0,255,255", tolerance);
+    _assertPixelApprox(canvas, 15,15, 0,0,0,255, "15,15", "0,0,0,255", tolerance);
+}
+
+function testDrawImageBitmap(source)
+{
+    var canvas = document.createElement("canvas");
+    canvas.width = 20;
+    canvas.height = 20;
+    var ctx = canvas.getContext("2d");
+    ctx.clearRect(0, 0, canvas.width, canvas.height);
+    return createImageBitmap(source).then(imageBitmap => {
+        ctx.drawImage(imageBitmap, 0, 0);
+        testCanvasDisplayingPattern(canvas);
+    });
+}
+
+function initializeTestCanvas(testCanvas)
+{
+    testCanvas.width = 20;
+    testCanvas.height = 20;
+    var testCtx = testCanvas.getContext("2d");
+    testCtx.fillStyle = "rgb(255, 0, 0)";
+    testCtx.fillRect(0, 0, 10, 10);
+    testCtx.fillStyle = "rgb(0, 255, 0)";
+    testCtx.fillRect(10, 0, 10, 10);
+    testCtx.fillStyle = "rgb(0, 0, 255)";
+    testCtx.fillRect(0, 10, 10, 10);
+    testCtx.fillStyle = "rgb(0, 0, 0)";
+    testCtx.fillRect(10, 10, 10, 10);
+}
+
+function initializeImageData(imgData, width, height)
+{
+    for (var i = 0; i < width * height * 4; i+=4) {
+        imgData.data[i] = 0;
+        imgData.data[i + 1] = 0;
+        imgData.data[i + 2] = 0;
+        imgData.data[i + 3] = 255; //alpha channel: 255
+    }
+    var halfWidth = width/2;
+    var halfHeight = height/2;
+    // initialize to R, G, B, Black, with each one 10*10 pixels
+    for (var i = 0; i < halfHeight; i++)
+        for (var j = 0; j < halfWidth; j++)
+            imgData.data[i * width * 4 + j * 4] = 255;
+    for (var i = 0; i < halfHeight; i++)
+        for (var j = halfWidth; j < width; j++)
+            imgData.data[i * width * 4 + j * 4 + 1] = 255;
+    for (var i = halfHeight; i < height; i++)
+        for (var j = 0; j < halfWidth; j++)
+            imgData.data[i * width * 4 + j * 4 + 2] = 255;
+}
+
+function create9x9CanvasWith2dContext()
+{
+    let c = document.createElement("canvas");
+    c.width = 9;
+    c.height = 9;
+    return [c, c.getContext("2d")];
+}
Property changes on: trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/common.js
___________________________________________________________________

Added: svn:eol-style

+native \ No newline at end of property

Added: svn:keywords

+Date Revision \ No newline at end of property

Added: svn:mime-type

+text/plain \ No newline at end of property

Added: trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/drawImage-ImageBitmap-expected.txt (0 => 223843)


--- trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/drawImage-ImageBitmap-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/drawImage-ImageBitmap-expected.txt	2017-10-23 17:51:08 UTC (rev 223843)
@@ -0,0 +1,8 @@
+
+PASS drawImage of ImageBitmap 
+PASS drawImage of ImageBitmap with cropping 
+PASS drawImage of ImageBitmap with cropping and different origin 
+PASS drawImage of ImageBitmap with cropping and different non-zero origin 
+PASS drawImage throws with InvalidStateError if the ImageBitmap is closed 
+PASS drawImage throws with IndexSizeError if the source rectangle of the ImageBitmap is empty 
+
Property changes on: trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/drawImage-ImageBitmap-expected.txt
___________________________________________________________________

Added: svn:eol-style

+native \ No newline at end of property

Added: svn:keywords

+Date Revision \ No newline at end of property

Added: svn:mime-type

+text/plain \ No newline at end of property

Added: trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/drawImage-ImageBitmap.html (0 => 223843)


--- trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/drawImage-ImageBitmap.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/drawImage-ImageBitmap.html	2017-10-23 17:51:08 UTC (rev 223843)
@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<html>
+<title>drawImage ImageBitmap test</title>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+<link rel="stylesheet" href=""
+<body>
+<script>
+// The target-blue-dot.png image is a 9x9 bitmap with a #00ff00 background
+// and a single #0000ff pixel right in the middle (at 4,4).
+
+(function() {
+    promise_test(function() {
+        return new Promise(function(resolve, reject) {
+            let img = new Image();
+            img._onload_ = function() { resolve(img); };
+            img.src = ""
+        }).then(function(img) {
+            return createImageBitmap(img);
+        }).then(function(imageBitmap) {
+            let [canvas, ctx] = create9x9CanvasWith2dContext();
+            ctx.drawImage(imageBitmap, 0, 0);
+            _assertPixel(canvas, 0,0, 0,255,0,255, "0,0", "0,255,0,255");
+            _assertPixel(canvas, 4,3, 0,255,0,255, "0,0", "0,255,0,255");
+            _assertPixel(canvas, 3,4, 0,255,0,255, "0,0", "0,255,0,255");
+            _assertPixel(canvas, 4,4, 0,0,255,255, "5,5", "0,0,255,255"); // Target blue dot.
+            _assertPixel(canvas, 5,4, 0,255,0,255, "0,0", "0,255,0,255");
+            _assertPixel(canvas, 4,5, 0,255,0,255, "0,0", "0,255,0,255");
+        });
+    }, "drawImage of ImageBitmap");
+
+    promise_test(function() {
+        return new Promise(function(resolve, reject) {
+            let img = new Image();
+            img._onload_ = function() { resolve(img); };
+            img.src = ""
+        }).then(function(img) {
+            return createImageBitmap(img);
+        }).then(function(imageBitmap) {
+            let [canvas, ctx] = create9x9CanvasWith2dContext();
+            ctx.drawImage(imageBitmap, 0, 0, 5, 5, 0, 0, 5, 5);
+            _assertPixel(canvas, 0,0, 0,255,0,255, "0,0", "0,255,0,255");
+            _assertPixel(canvas, 4,3, 0,255,0,255, "0,0", "0,255,0,255");
+            _assertPixel(canvas, 3,4, 0,255,0,255, "0,0", "0,255,0,255");
+            _assertPixel(canvas, 4,4, 0,0,255,255, "5,5", "0,0,255,255"); // Target blue dot.
+            _assertPixel(canvas, 5,4, 0,0,0,0, "0,0", "0,0,0,0"); // Didn't draw into these parts.
+            _assertPixel(canvas, 4,5, 0,0,0,0, "0,0", "0,0,0,0");
+        });
+    }, "drawImage of ImageBitmap with cropping");
+
+    promise_test(function() {
+        return new Promise(function(resolve, reject) {
+            let img = new Image();
+            img._onload_ = function() { resolve(img); };
+            img.src = ""
+        }).then(function(img) {
+            return createImageBitmap(img);
+        }).then(function(imageBitmap) {
+            let [canvas, ctx] = create9x9CanvasWith2dContext();
+            ctx.drawImage(imageBitmap, 2, 2, 5, 5, 0, 0, 5, 5);
+            _assertPixel(canvas, 0,0, 0,255,0,255, "0,0", "0,255,0,255");
+            _assertPixel(canvas, 2,1, 0,255,0,255, "0,0", "0,255,0,255");
+            _assertPixel(canvas, 1,2, 0,255,0,255, "0,0", "0,255,0,255");
+            _assertPixel(canvas, 2,2, 0,0,255,255, "5,5", "0,0,255,255");
+            _assertPixel(canvas, 3,2, 0,255,0,255, "0,0", "0,255,0,255");
+            _assertPixel(canvas, 2,3, 0,255,0,255, "0,0", "0,255,0,255");
+            _assertPixel(canvas, 8,8, 0,0,0,0, "0,0", "0,0,0,0");
+        });
+    }, "drawImage of ImageBitmap with cropping and different origin");
+
+    promise_test(function() {
+        return new Promise(function(resolve, reject) {
+            let img = new Image();
+            img._onload_ = function() { resolve(img); };
+            img.src = ""
+        }).then(function(img) {
+            return createImageBitmap(img);
+        }).then(function(imageBitmap) {
+            let [canvas, ctx] = create9x9CanvasWith2dContext();
+            ctx.drawImage(imageBitmap, 2, 2, 5, 5, 2, 2, 5, 5);
+            _assertPixel(canvas, 0,0, 0,0,0,0, "0,0", "0,0,0,0"); // Didn't draw here.
+            _assertPixel(canvas, 4,3, 0,255,0,255, "0,0", "0,255,0,255");
+            _assertPixel(canvas, 3,4, 0,255,0,255, "0,0", "0,255,0,255");
+            _assertPixel(canvas, 4,4, 0,0,255,255, "5,5", "0,0,255,255"); // Target blue dot.
+            _assertPixel(canvas, 5,4, 0,255,0,255, "0,0", "0,255,0,255");
+            _assertPixel(canvas, 4,5, 0,255,0,255, "0,0", "0,255,0,255");
+            _assertPixel(canvas, 8,8, 0,0,0,0, "0,0", "0,0,0,0");
+        });
+    }, "drawImage of ImageBitmap with cropping and different non-zero origin");
+
+    // TODO: Add tests for tainted origin.
+    // TODO: Add tests with different blending.
+
+    promise_test(function(t) {
+        return new Promise(function(resolve, reject) {
+            let img = new Image();
+            img._onload_ = function() { resolve(img); };
+            img.src = ""
+        }).then(function(img) {
+            return createImageBitmap(img);
+        }).then(function(imageBitmap) {
+            imageBitmap.close();
+            let [canvas, ctx] = create9x9CanvasWith2dContext();
+            assert_throws('InvalidStateError', function () {
+                ctx.drawImage(imageBitmap, 0, 0);
+            }, "A closed ImageBitmap can't be drawn.");
+        });
+    }, "drawImage throws with InvalidStateError if the ImageBitmap is closed");
+
+    promise_test(function(t) {
+        return new Promise(function(resolve, reject) {
+            let img = new Image();
+            img._onload_ = function() { resolve(img); };
+            img.src = ""
+        }).then(function(img) {
+            return createImageBitmap(img);
+        }).then(function(imageBitmap) {
+            let [canvas, ctx] = create9x9CanvasWith2dContext();
+            assert_throws('IndexSizeError', function () {
+                ctx.drawImage(imageBitmap, 0, 0, 0, 0, 0, 0, 9, 9);
+            }, "drawImage with an empty source rectangle should fail.");
+        });
+    }, "drawImage throws with IndexSizeError if the source rectangle of the ImageBitmap is empty");
+})();
+</script>
+</body>
+</html>
Property changes on: trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/drawImage-ImageBitmap.html
___________________________________________________________________

Added: svn:eol-style

+native \ No newline at end of property

Added: svn:keywords

+Date Revision \ No newline at end of property

Added: svn:mime-type

+text/html \ No newline at end of property

Added: trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/target-blue-dot.png


(Binary files differ)
Index: trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/target-blue-dot.png =================================================================== --- trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/target-blue-dot.png 2017-10-23 17:49:22 UTC (rev 223842) +++ trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/target-blue-dot.png 2017-10-23 17:51:08 UTC (rev 223843) Property changes on: trunk/LayoutTests/http/wpt/2dcontext/imagebitmap/target-blue-dot.png ___________________________________________________________________

Added: svn:mime-type

+image/png \ No newline at end of property

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (223842 => 223843)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2017-10-23 17:49:22 UTC (rev 223842)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2017-10-23 17:51:08 UTC (rev 223843)
@@ -1,3 +1,15 @@
+2017-10-22  Dean Jackson  <[email protected]>
+
+        Implement drawImage(ImageBitmap) on 2d canvas
+        https://bugs.webkit.org/show_bug.cgi?id=178653
+        <rdar://problem/35104360>
+
+        Reviewed by Antoine Quint.
+
+        Update expected results now that drawImage is implemented.
+
+        * web-platform-tests/2dcontext/imagebitmap/createImageBitmap-drawImage-expected.txt:
+
 2017-10-20  Dean Jackson  <[email protected]>
 
         Add createImageBitmap to Window and Worker

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-drawImage-expected.txt (223842 => 223843)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-drawImage-expected.txt	2017-10-23 17:49:22 UTC (rev 223842)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-drawImage-expected.txt	2017-10-23 17:51:08 UTC (rev 223843)
@@ -1,10 +1,10 @@
 
 Harness Error (TIMEOUT), message = null
 
-FAIL createImageBitmap from a HTMLImageElement, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL createImageBitmap from a Blob, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL createImageBitmap from a HTMLCanvasElement, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL createImageBitmap from an ImageBitmap, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL createImageBitmap from an ImageData, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: Type error"
+PASS createImageBitmap from a HTMLImageElement, and drawImage on the created ImageBitmap 
+FAIL createImageBitmap from a Blob, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
+FAIL createImageBitmap from a HTMLCanvasElement, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
+FAIL createImageBitmap from an ImageBitmap, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
+FAIL createImageBitmap from an ImageData, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
 TIMEOUT createImageBitmap from a HTMLVideoElement, and drawImage on the created ImageBitmap Test timed out
 

Modified: trunk/Source/WebCore/ChangeLog (223842 => 223843)


--- trunk/Source/WebCore/ChangeLog	2017-10-23 17:49:22 UTC (rev 223842)
+++ trunk/Source/WebCore/ChangeLog	2017-10-23 17:51:08 UTC (rev 223843)
@@ -1,3 +1,36 @@
+2017-10-22  Dean Jackson  <[email protected]>
+
+        Implement drawImage(ImageBitmap) on 2d canvas
+        https://bugs.webkit.org/show_bug.cgi?id=178653
+        <rdar://problem/35104360>
+
+        Reviewed by Antoine Quint.
+
+        Implement CanvasRenderingContext2D::drawImage with ImageBitmap.
+        It's probably not going to be a very common operation, but
+        it importantly allows us to test the ImageBitmap creation
+        code.
+
+        Test: http/wpt/2dcontext/imagebitmap/drawImage-ImageBitmap.html
+
+        * html/ImageBitmap.cpp:
+        (WebCore::taintsOrigin): New helper function to determine if a
+        CachedImage would provide a clean origin.
+        (WebCore::ImageBitmap::createPromise): Set the flag that records
+        if this ImageBitmap has a clean origin.
+        * html/ImageBitmap.h:
+        (WebCore::ImageBitmap::buffer): Exposes the ImageBuffer backing
+        store, allowing access to the data for drawing.
+        (WebCore::ImageBitmap::originClean const): Is this ImageBitmap
+        going to taint a destination.
+        * html/canvas/CanvasRenderingContext.cpp:
+        (WebCore::CanvasRenderingContext::wouldTaintOrigin): Implement
+        the ImageBitmap version of this template function.
+        * html/canvas/CanvasRenderingContext.h:
+        * html/canvas/CanvasRenderingContext2D.cpp:
+        (WebCore::CanvasRenderingContext2D::drawImage): Implement the
+        actual drawing of an ImageBitmap.
+
 2017-10-23  Daniel Bates  <[email protected]>
 
         Unreviewed, rolling out r223699.

Modified: trunk/Source/WebCore/html/ImageBitmap.cpp (223842 => 223843)


--- trunk/Source/WebCore/html/ImageBitmap.cpp	2017-10-23 17:49:22 UTC (rev 223842)
+++ trunk/Source/WebCore/html/ImageBitmap.cpp	2017-10-23 17:51:08 UTC (rev 223843)
@@ -89,6 +89,21 @@
     );
 }
 
+static bool taintsOrigin(CachedImage& cachedImage)
+{
+    auto* image = cachedImage.image();
+    if (!image)
+        return false;
+
+    if (!image->hasSingleSecurityOrigin())
+        return true;
+
+    if (!cachedImage.isCORSSameOrigin())
+        return true;
+
+    return false;
+}
+
 void ImageBitmap::createPromise(ScriptExecutionContext&, RefPtr<HTMLImageElement>& imageElement, ImageBitmapOptions&& options, std::optional<IntRect> rect, ImageBitmap::Promise&& promise)
 {
     UNUSED_PARAM(options);
@@ -147,6 +162,8 @@
     //    entry settings object, then set the origin-clean flag of the ImageBitmap object's
     //    bitmap to false.
 
+    imageBitmap->m_originClean = !taintsOrigin(*cachedImage);
+
     // 10. Return a new promise, but continue running these steps in parallel.
     // 11. Resolve the promise with the new ImageBitmap object as the value.
 

Modified: trunk/Source/WebCore/html/ImageBitmap.h (223842 => 223843)


--- trunk/Source/WebCore/html/ImageBitmap.h	2017-10-23 17:49:22 UTC (rev 223842)
+++ trunk/Source/WebCore/html/ImageBitmap.h	2017-10-23 17:51:08 UTC (rev 223843)
@@ -70,6 +70,10 @@
 
     bool isDetached() const { return m_detached; }
 
+    ImageBuffer* buffer() { return m_bitmapData.get(); }
+
+    bool originClean() const { return m_originClean; }
+
 private:
     friend class PendingImageBitmap;
 
@@ -87,6 +91,7 @@
 
     std::unique_ptr<ImageBuffer> m_bitmapData;
     bool m_detached { false };
+    bool m_originClean { false };
 };
 
 }

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext.cpp (223842 => 223843)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext.cpp	2017-10-23 17:49:22 UTC (rev 223842)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext.cpp	2017-10-23 17:51:08 UTC (rev 223843)
@@ -31,6 +31,7 @@
 #include "HTMLImageElement.h"
 #include "HTMLVideoElement.h"
 #include "Image.h"
+#include "ImageBitmap.h"
 #include "URL.h"
 #include "SecurityOrigin.h"
 
@@ -103,6 +104,14 @@
     return false;
 }
 
+bool CanvasRenderingContext::wouldTaintOrigin(const ImageBitmap* imageBitmap)
+{
+    if (!imageBitmap || !canvas().originClean())
+        return false;
+
+    return !imageBitmap->originClean();
+}
+
 bool CanvasRenderingContext::wouldTaintOrigin(const URL& url)
 {
     if (!canvas().originClean())

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext.h (223842 => 223843)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext.h	2017-10-23 17:49:22 UTC (rev 223842)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext.h	2017-10-23 17:51:08 UTC (rev 223843)
@@ -37,6 +37,7 @@
 class HTMLCanvasElement;
 class HTMLImageElement;
 class HTMLVideoElement;
+class ImageBitmap;
 class URL;
 class WebGLObject;
 
@@ -73,6 +74,7 @@
     bool wouldTaintOrigin(const HTMLCanvasElement*);
     bool wouldTaintOrigin(const HTMLImageElement*);
     bool wouldTaintOrigin(const HTMLVideoElement*);
+    bool wouldTaintOrigin(const ImageBitmap*);
     bool wouldTaintOrigin(const URL&);
 
     template<class T> void checkOrigin(const T* arg)

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp (223842 => 223843)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp	2017-10-23 17:49:22 UTC (rev 223842)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp	2017-10-23 17:51:08 UTC (rev 223843)
@@ -1669,10 +1669,47 @@
 
 #endif
 
-ExceptionOr<void> CanvasRenderingContext2D::drawImage(ImageBitmap&, const FloatRect&, const FloatRect&)
+ExceptionOr<void> CanvasRenderingContext2D::drawImage(ImageBitmap& imageBitmap, const FloatRect& srcRect, const FloatRect& dstRect)
 {
-    // FIXME: Implement.
-    return Exception { TypeError };
+    if (!imageBitmap.width() || !imageBitmap.height())
+        return Exception { InvalidStateError };
+
+    if (!srcRect.width() || !srcRect.height())
+        return Exception { IndexSizeError };
+
+    FloatRect srcBitmapRect = FloatRect(FloatPoint(), FloatSize(imageBitmap.width(), imageBitmap.height()));
+
+    if (!srcBitmapRect.contains(normalizeRect(srcRect)) || !dstRect.width() || !dstRect.height())
+        return { };
+
+    GraphicsContext* c = drawingContext();
+    if (!c)
+        return { };
+    if (!state().hasInvertibleTransform)
+        return { };
+
+    ImageBuffer* buffer = imageBitmap.buffer();
+    if (!buffer)
+        return { };
+
+    checkOrigin(&imageBitmap);
+
+    if (rectContainsCanvas(dstRect)) {
+        c->drawImageBuffer(*buffer, dstRect, srcRect, ImagePaintingOptions(state().globalComposite, state().globalBlend));
+        didDrawEntireCanvas();
+    } else if (isFullCanvasCompositeMode(state().globalComposite)) {
+        fullCanvasCompositedDrawImage(*buffer, dstRect, srcRect, state().globalComposite);
+        didDrawEntireCanvas();
+    } else if (state().globalComposite == CompositeCopy) {
+        clearCanvas();
+        c->drawImageBuffer(*buffer, dstRect, srcRect, ImagePaintingOptions(state().globalComposite, state().globalBlend));
+        didDrawEntireCanvas();
+    } else {
+        c->drawImageBuffer(*buffer, dstRect, srcRect, ImagePaintingOptions(state().globalComposite, state().globalBlend));
+        didDraw(dstRect);
+    }
+
+    return { };
 }
 
 void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement& imageElement, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, const String& compositeOperation)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to