Diff
Modified: trunk/LayoutTests/ChangeLog (241839 => 241840)
--- trunk/LayoutTests/ChangeLog 2019-02-20 22:25:23 UTC (rev 241839)
+++ trunk/LayoutTests/ChangeLog 2019-02-20 22:28:13 UTC (rev 241840)
@@ -1,3 +1,13 @@
+2019-02-20 Said Abou-Hallawa <sabouhall...@apple.com>
+
+ drawImage() clears the canvas if it's the source of the image and globalCompositeOperation is "copy"
+ https://bugs.webkit.org/show_bug.cgi?id=194746
+
+ Reviewed by Dean Jackson.
+
+ * fast/canvas/canvas-drawImage-composite-copy-expected.html: Added.
+ * fast/canvas/canvas-drawImage-composite-copy.html: Added.
+
2019-02-20 Shawn Roberts <srobe...@apple.com>
[ Mac WK2 ] REGRESSION (r231450) Layout Test http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-iframe-with-enforced-and-report-policies.html is a flaky failure
Added: trunk/LayoutTests/fast/canvas/canvas-drawImage-composite-copy-expected.html (0 => 241840)
--- trunk/LayoutTests/fast/canvas/canvas-drawImage-composite-copy-expected.html (rev 0)
+++ trunk/LayoutTests/fast/canvas/canvas-drawImage-composite-copy-expected.html 2019-02-20 22:28:13 UTC (rev 241840)
@@ -0,0 +1,12 @@
+<body>
+ <canvas id="canvas" width="200" height="200"></canvas>
+ <script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext("2d");
+ const width = canvas.width;
+ const height = canvas.height;
+
+ ctx.fillStyle = "green";
+ ctx.fillRect(0, 0, width / 2, height / 2);
+ </script>
+</body>
Added: trunk/LayoutTests/fast/canvas/canvas-drawImage-composite-copy.html (0 => 241840)
--- trunk/LayoutTests/fast/canvas/canvas-drawImage-composite-copy.html (rev 0)
+++ trunk/LayoutTests/fast/canvas/canvas-drawImage-composite-copy.html 2019-02-20 22:28:13 UTC (rev 241840)
@@ -0,0 +1,21 @@
+<body>
+ <canvas id="canvas" width="200" height="200"></canvas>
+ <script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext("2d");
+ const width = canvas.width;
+ const height = canvas.height;
+
+ ctx.fillStyle = "green";
+ ctx.fillRect(width / 2, height / 2, width / 2, height / 2);
+
+ ctx.globalCompositeOperation = "copy";
+ ctx.imageSmoothingEnabled = false;
+
+ ctx.drawImage(
+ canvas,
+ width / 2, height / 2, width / 2, height / 2,
+ 0, 0, width / 2, height / 2
+ );
+ </script>
+</body>
Modified: trunk/Source/WebCore/ChangeLog (241839 => 241840)
--- trunk/Source/WebCore/ChangeLog 2019-02-20 22:25:23 UTC (rev 241839)
+++ trunk/Source/WebCore/ChangeLog 2019-02-20 22:28:13 UTC (rev 241840)
@@ -1,3 +1,23 @@
+2019-02-20 Said Abou-Hallawa <sabouhall...@apple.com>
+
+ drawImage() clears the canvas if it's the source of the image and globalCompositeOperation is "copy"
+ https://bugs.webkit.org/show_bug.cgi?id=194746
+
+ Reviewed by Dean Jackson.
+
+ Test: fast/canvas/canvas-drawImage-composite-copy.html
+
+ If the source canvas of drawImage() is the same as the destination and
+ globalCompositeOperation is set to "copy", copy the srcRect from the
+ canvas to a temporary buffer before calling clearCanvas() then drawImage
+ from this temporary buffer.
+
+ * html/canvas/CanvasRenderingContext2DBase.cpp:
+ (WebCore::CanvasRenderingContext2DBase::drawImage):
+ * platform/graphics/ImageBuffer.cpp:
+ (WebCore::ImageBuffer::copyRectToBuffer):
+ * platform/graphics/ImageBuffer.h:
+
2019-02-20 Simon Fraser <simon.fra...@apple.com>
REGRESSION (r241788>): ASSERTION FAILED: !m_normalFlowListDirty in TestWebKitAPI.WebKit.ResizeReversePaginatedWebView test
Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp (241839 => 241840)
--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp 2019-02-20 22:25:23 UTC (rev 241839)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp 2019-02-20 22:28:13 UTC (rev 241840)
@@ -1643,8 +1643,15 @@
fullCanvasCompositedDrawImage(*buffer, dstRect, srcRect, state().globalComposite);
didDrawEntireCanvas();
} else if (state().globalComposite == CompositeCopy) {
- clearCanvas();
- c->drawImageBuffer(*buffer, dstRect, srcRect, ImagePaintingOptions(state().globalComposite, state().globalBlend));
+ if (&sourceCanvas == &canvasBase()) {
+ if (auto copy = buffer->copyRectToBuffer(srcRect, ColorSpaceSRGB, *c)) {
+ clearCanvas();
+ c->drawImageBuffer(*copy, dstRect, { { }, srcRect.size() }, ImagePaintingOptions(state().globalComposite, state().globalBlend));
+ }
+ } else {
+ clearCanvas();
+ c->drawImageBuffer(*buffer, dstRect, srcRect, ImagePaintingOptions(state().globalComposite, state().globalBlend));
+ }
didDrawEntireCanvas();
} else {
c->drawImageBuffer(*buffer, dstRect, srcRect, ImagePaintingOptions(state().globalComposite, state().globalBlend));
Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp (241839 => 241840)
--- trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp 2019-02-20 22:25:23 UTC (rev 241839)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp 2019-02-20 22:28:13 UTC (rev 241840)
@@ -194,6 +194,21 @@
}
#endif
+std::unique_ptr<ImageBuffer> ImageBuffer::copyRectToBuffer(const FloatRect& rect, ColorSpace colorSpace, const GraphicsContext& context)
+{
+ if (rect.isEmpty())
+ return nullptr;
+
+ IntSize scaledSize = ImageBuffer::compatibleBufferSize(rect.size(), context);
+
+ auto buffer = ImageBuffer::createCompatibleBuffer(scaledSize, 1, colorSpace, context);
+ if (!buffer)
+ return nullptr;
+
+ buffer->context().drawImageBuffer(*this, -rect.location());
+ return buffer;
+}
+
std::unique_ptr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize& size, ColorSpace colorSpace, const GraphicsContext& context)
{
if (size.isEmpty())
Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.h (241839 => 241840)
--- trunk/Source/WebCore/platform/graphics/ImageBuffer.h 2019-02-20 22:25:23 UTC (rev 241839)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.h 2019-02-20 22:28:13 UTC (rev 241840)
@@ -71,6 +71,9 @@
WEBCORE_EXPORT static std::unique_ptr<ImageBuffer> create(const FloatSize&, RenderingMode, const GraphicsContext*, float resolutionScale = 1, ColorSpace = ColorSpaceSRGB, const HostWindow* = nullptr);
#endif
+ // Create an image buffer compatible with the context and copy rect from this buffer into this new one.
+ std::unique_ptr<ImageBuffer> copyRectToBuffer(const FloatRect&, ColorSpace, const GraphicsContext&);
+
// Create an image buffer compatible with the context, with suitable resolution for drawing into the buffer and then into this context.
static std::unique_ptr<ImageBuffer> createCompatibleBuffer(const FloatSize&, const GraphicsContext&);
static std::unique_ptr<ImageBuffer> createCompatibleBuffer(const FloatSize&, ColorSpace, const GraphicsContext&);