2010-09-23 Matthew Delaney <mdelaney@apple.com>
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Sep 2010 19:15:48 +0000 (19:15 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Sep 2010 19:15:48 +0000 (19:15 +0000)
        Reviewed by Oliver Hunt.

        context.drawImage with (source rect's height) = -(input image's native height) draws nothing
        https://bugs.webkit.org/show_bug.cgi?id=46243

        These test simply exercise using negative widths and heights for the source rect in ctx.drawImage calls.

        * canvas/philip/tests/2d.drawImage.negativeSourceHeight-expected.txt: Added.
        * canvas/philip/tests/2d.drawImage.negativeSourceHeight.html: Added.
        * canvas/philip/tests/2d.drawImage.negativeSourceHeight2-expected.txt: Added.
        * canvas/philip/tests/2d.drawImage.negativeSourceHeight2.html: Added.
        * canvas/philip/tests/2d.drawImage.negativeSourceHeightAndWidth-expected.txt: Added.
        * canvas/philip/tests/2d.drawImage.negativeSourceHeightAndWidth.html: Added.
2010-09-23  Matthew Delaney  <mdelaney@apple.com>

        Reviewed by Oliver Hunt.

        context.drawImage with (source rect's height) = -(input image's native height) draws nothing
        https://bugs.webkit.org/show_bug.cgi?id=46243

        This patch changes canvasrenderingcontext2d's drawImage with an image element to
        normalize the source and dest rects to acheive the desired canvas spec behavior
        of allowing negative widths and heights that don't cause flipping and fix the
        adverse behavior of specifying a source rect height of negative the source image's height

        Tests: canvas/philip/tests/2d.drawImage.negativeSourceHeight.html
               canvas/philip/tests/2d.drawImage.negativeSourceHeight2.html
               canvas/philip/tests/2d.drawImage.negativeSourceHeightAndWidth.html

        * html/canvas/CanvasRenderingContext2D.cpp: Normalize rects in drawImage before calling
        lower level draw calls.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@68176 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeight-expected.txt [new file with mode: 0644]
LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeight.html [new file with mode: 0644]
LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeight2-expected.txt [new file with mode: 0644]
LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeight2.html [new file with mode: 0644]
LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeightAndWidth-expected.txt [new file with mode: 0644]
LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeightAndWidth.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/html/canvas/CanvasRenderingContext2D.cpp

index 5d949dc..43a3a28 100644 (file)
@@ -1,3 +1,19 @@
+2010-09-23  Matthew Delaney  <mdelaney@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        context.drawImage with (source rect's height) = -(input image's native height) draws nothing
+        https://bugs.webkit.org/show_bug.cgi?id=46243
+
+        These test simply exercise using negative widths and heights for the source rect in ctx.drawImage calls.
+
+        * canvas/philip/tests/2d.drawImage.negativeSourceHeight-expected.txt: Added.
+        * canvas/philip/tests/2d.drawImage.negativeSourceHeight.html: Added.
+        * canvas/philip/tests/2d.drawImage.negativeSourceHeight2-expected.txt: Added.
+        * canvas/philip/tests/2d.drawImage.negativeSourceHeight2.html: Added.
+        * canvas/philip/tests/2d.drawImage.negativeSourceHeightAndWidth-expected.txt: Added.
+        * canvas/philip/tests/2d.drawImage.negativeSourceHeightAndWidth.html: Added.
+
 2010-09-23  Nate Chapin  <japhet@chromium.org>
 
         Unreviewed, Chromium expectations tweak.
diff --git a/LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeight-expected.txt b/LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeight-expected.txt
new file mode 100644 (file)
index 0000000..40350d1
--- /dev/null
@@ -0,0 +1,9 @@
+< [index] >
+2d.drawImage.negativeSourceHeight
+Negative source width/height represents the correct rectangle
+References: 2d.drawImage.direction
+Actual output:
+Expected output:
+
+Passed
+
diff --git a/LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeight.html b/LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeight.html
new file mode 100644 (file)
index 0000000..60cf4b7
--- /dev/null
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.drawImage.negativeSourceHeight</title>
+<script src="../tests.js"></script>
+<link rel="stylesheet" href="../tests.css">
+<link rel="prev" href="2d.drawImage.negativesource.html" title="2d.drawImage.negativesource">
+<link rel="next" href="2d.drawImage.negativedir.html" title="2d.drawImage.negativedir">
+<body class="show_output">
+<p>
+ <a href="2d.drawImage.negativesource.html" accesskey="p" title="[p] 2d.drawImage.negativesource">&lt;</a>
+ <a href="index.html">[index]</a>
+ <a href="2d.drawImage.negativedir.html" accesskey="n" title="[n] 2d.drawImage.negativedir">&gt;</a>
+<h1><a href="index.2d.html">2d</a>.<a href="index.2d.drawImage.html">drawImage</a>.negativeSourceHeight</h1>
+<p class="desc">Negative source width/height represents the correct rectangle</p>
+<div class="refs">References:
+<ul>
+<li><a href="spec.html#testrefs.2d.drawImage.direction">2d.drawImage.direction</a>
+
+</ul>
+</div>
+
+<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="green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+_addTest(function(canvas, ctx) {
+
+ctx.fillStyle = '#f00';
+ctx.fillRect(0, 0, 100, 50);
+
+ctx.drawImage(document.getElementById('ggrr-256x256.png'), 0, 128, 256, -128, 0, 0, 100, 50);
+//ctx.drawImage(document.getElementById('ggrr-256x256.png'), 512, 512, -512, -512, 0, 0, 512, 512);
+
+_assertPixelApprox(canvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 48,1, 0,255,0,255, "48,1", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 48,48, 0,255,0,255, "48,48", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 51,1, 0,255,0,255, "51,1", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 51,48, 0,255,0,255, "51,48", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 25,25, 0,255,0,255, "25,25", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 75,25, 0,255,0,255, "75,25", "0,255,0,255", 2);
+
+
+});
+</script>
+<img src="../images/ggrr-256x256.png" id="ggrr-256x256.png" class="resource">
+
diff --git a/LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeight2-expected.txt b/LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeight2-expected.txt
new file mode 100644 (file)
index 0000000..e22440d
--- /dev/null
@@ -0,0 +1,9 @@
+< [index] >
+2d.drawImage.negativeSourceHeight2
+Negative source width/height represents the correct rectangle
+References: 2d.drawImage.direction
+Actual output:
+Expected output:
+
+Passed
+
diff --git a/LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeight2.html b/LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeight2.html
new file mode 100644 (file)
index 0000000..a1fde45
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.drawImage.negativeSourceHeight2</title>
+<script src="../tests.js"></script>
+<link rel="stylesheet" href="../tests.css">
+<link rel="prev" href="2d.drawImage.negativesource.html" title="2d.drawImage.negativesource">
+<link rel="next" href="2d.drawImage.negativedir.html" title="2d.drawImage.negativedir">
+<body class="show_output">
+<p>
+ <a href="2d.drawImage.negativesource.html" accesskey="p" title="[p] 2d.drawImage.negativesource">&lt;</a>
+ <a href="index.html">[index]</a>
+ <a href="2d.drawImage.negativedir.html" accesskey="n" title="[n] 2d.drawImage.negativedir">&gt;</a>
+<h1><a href="index.2d.html">2d</a>.<a href="index.2d.drawImage.html">drawImage</a>.negativeSourceHeight2</h1>
+<p class="desc">Negative source width/height represents the correct rectangle</p>
+<div class="refs">References:
+<ul>
+<li><a href="spec.html#testrefs.2d.drawImage.direction">2d.drawImage.direction</a>
+
+</ul>
+</div>
+
+<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="green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+_addTest(function(canvas, ctx) {
+
+ctx.fillStyle = '#f00';
+ctx.fillRect(0, 0, 100, 50);
+
+ctx.drawImage(document.getElementById('green.png'), 0, 50, 100, -50, 0, 0, 100, 50);
+
+_assertPixelApprox(canvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 48,1, 0,255,0,255, "48,1", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 48,48, 0,255,0,255, "48,48", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 51,1, 0,255,0,255, "51,1", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 51,48, 0,255,0,255, "51,48", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 25,25, 0,255,0,255, "25,25", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 75,25, 0,255,0,255, "75,25", "0,255,0,255", 2);
+
+
+});
+</script>
+<img src="../images/green.png" id="green.png" class="resource">
+
diff --git a/LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeightAndWidth-expected.txt b/LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeightAndWidth-expected.txt
new file mode 100644 (file)
index 0000000..c1968f4
--- /dev/null
@@ -0,0 +1,9 @@
+< [index] >
+2d.drawImage.negativeSourceHeightAndWidth
+Negative source width/height represents the correct rectangle
+References: 2d.drawImage.direction
+Actual output:
+Expected output:
+
+Passed
+
diff --git a/LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeightAndWidth.html b/LayoutTests/canvas/philip/tests/2d.drawImage.negativeSourceHeightAndWidth.html
new file mode 100644 (file)
index 0000000..8fcde4a
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.drawImage.negativeSourceHeightAndWidth</title>
+<script src="../tests.js"></script>
+<link rel="stylesheet" href="../tests.css">
+<link rel="prev" href="2d.drawImage.negativesource.html" title="2d.drawImage.negativesource">
+<link rel="next" href="2d.drawImage.negativedir.html" title="2d.drawImage.negativedir">
+<body class="show_output">
+<p>
+ <a href="2d.drawImage.negativesource.html" accesskey="p" title="[p] 2d.drawImage.negativesource">&lt;</a>
+ <a href="index.html">[index]</a>
+ <a href="2d.drawImage.negativedir.html" accesskey="n" title="[n] 2d.drawImage.negativedir">&gt;</a>
+<h1><a href="index.2d.html">2d</a>.<a href="index.2d.drawImage.html">drawImage</a>.negativeSourceHeightAndWidth</h1>
+<p class="desc">Negative source width/height represents the correct rectangle</p>
+<div class="refs">References:
+<ul>
+<li><a href="spec.html#testrefs.2d.drawImage.direction">2d.drawImage.direction</a>
+
+</ul>
+</div>
+
+<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="green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+_addTest(function(canvas, ctx) {
+
+ctx.fillStyle = '#f00';
+ctx.fillRect(0, 0, 100, 50);
+
+ctx.drawImage(document.getElementById('green.png'), 100, 50, -100, -50, 0, 0, 100, 50);
+
+_assertPixelApprox(canvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 48,1, 0,255,0,255, "48,1", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 48,48, 0,255,0,255, "48,48", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 51,1, 0,255,0,255, "51,1", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 51,48, 0,255,0,255, "51,48", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 25,25, 0,255,0,255, "25,25", "0,255,0,255", 2);
+_assertPixelApprox(canvas, 75,25, 0,255,0,255, "75,25", "0,255,0,255", 2);
+
+
+});
+</script>
+<img src="../images/green.png" id="green.png" class="resource">
+
index 608e35b..7619efc 100644 (file)
@@ -1,3 +1,22 @@
+2010-09-23  Matthew Delaney  <mdelaney@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        context.drawImage with (source rect's height) = -(input image's native height) draws nothing
+        https://bugs.webkit.org/show_bug.cgi?id=46243
+
+        This patch changes canvasrenderingcontext2d's drawImage with an image element to
+        normalize the source and dest rects to acheive the desired canvas spec behavior
+        of allowing negative widths and heights that don't cause flipping and fix the
+        adverse behavior of specifying a source rect height of negative the source image's height
+
+        Tests: canvas/philip/tests/2d.drawImage.negativeSourceHeight.html
+               canvas/philip/tests/2d.drawImage.negativeSourceHeight2.html
+               canvas/philip/tests/2d.drawImage.negativeSourceHeightAndWidth.html
+
+        * html/canvas/CanvasRenderingContext2D.cpp: Normalize rects in drawImage before calling
+        lower level draw calls.
+
 2010-09-23  Renata Hodovan  <reni@inf.u-szeged.hu>
 
         Reviewed by Dirk Schulze.
index 0fb7ed5..134ab67 100644 (file)
@@ -1186,18 +1186,21 @@ void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRec
         || !isfinite(srcRect.x()) || !isfinite(srcRect.y()) || !isfinite(srcRect.width()) || !isfinite(srcRect.height()))
         return;
 
+    if (!dstRect.width() || !dstRect.height())
+        return;
+
     if (!image->complete())
         return;
 
+    FloatRect normalizedSrcRect = normalizeRect(srcRect);
+    FloatRect normalizedDstRect = normalizeRect(dstRect);
+
     FloatRect imageRect = FloatRect(FloatPoint(), size(image));
-    if (!imageRect.contains(normalizeRect(srcRect)) || !srcRect.width() || !srcRect.height()) {
+    if (!imageRect.contains(normalizedSrcRect) || !srcRect.width() || !srcRect.height()) {
         ec = INDEX_SIZE_ERR;
         return;
     }
 
-    if (!dstRect.width() || !dstRect.height())
-        return;
-
     GraphicsContext* c = drawingContext();
     if (!c)
         return;
@@ -1214,8 +1217,8 @@ void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRec
     if (canvas()->originClean() && !cachedImage->image()->hasSingleSecurityOrigin())
         canvas()->setOriginTainted();
 
-    FloatRect sourceRect = c->roundToDevicePixels(srcRect);
-    FloatRect destRect = c->roundToDevicePixels(dstRect);
+    FloatRect sourceRect = c->roundToDevicePixels(normalizedSrcRect);
+    FloatRect destRect = c->roundToDevicePixels(normalizedDstRect);
     c->drawImage(cachedImage->image(), DeviceColorSpace, destRect, sourceRect, state().m_globalComposite);
     didDraw(destRect);
 }