Title: [259567] trunk
Revision
259567
Author
commit-qu...@webkit.org
Date
2020-04-06 01:03:17 -0700 (Mon, 06 Apr 2020)

Log Message

CanvasRenderingContext2D.drawImage should ignore the EXIF orientation if the image-orientation is none
https://bugs.webkit.org/show_bug.cgi?id=209849

Patch by Said Abou-Hallawa <sabouhall...@apple.com> on 2020-04-06
Reviewed by Darin Adler.

Source/WebCore:

drawImage() will get the image-orientation of the HTMLImageElement from
its computed style. This will be passed to GraphicsContext::drawImage()
in the ImagePaintingOptions. Previously we were passing FromImage always.

Test: fast/images/image-orientation-none-canvas.html

* html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::CanvasRenderingContext2DBase::drawImage):
* html/canvas/CanvasRenderingContext2DBase.h:

LayoutTests:

* fast/images/image-orientation-none-canvas-expected.html: Added.
* fast/images/image-orientation-none-canvas.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (259566 => 259567)


--- trunk/LayoutTests/ChangeLog	2020-04-06 06:04:44 UTC (rev 259566)
+++ trunk/LayoutTests/ChangeLog	2020-04-06 08:03:17 UTC (rev 259567)
@@ -1,3 +1,13 @@
+2020-04-06  Said Abou-Hallawa  <sabouhall...@apple.com>
+
+        CanvasRenderingContext2D.drawImage should ignore the EXIF orientation if the image-orientation is none
+        https://bugs.webkit.org/show_bug.cgi?id=209849
+
+        Reviewed by Darin Adler.
+
+        * fast/images/image-orientation-none-canvas-expected.html: Added.
+        * fast/images/image-orientation-none-canvas.html: Added.
+
 2020-04-05  Manuel Rego Casasnovas  <r...@igalia.com>
 
         Computed style for "outline-offset" is wrong when "outline-style" is "none"

Added: trunk/LayoutTests/fast/images/image-orientation-none-canvas-expected.html (0 => 259567)


--- trunk/LayoutTests/fast/images/image-orientation-none-canvas-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/images/image-orientation-none-canvas-expected.html	2020-04-06 08:03:17 UTC (rev 259567)
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<style>
+    div.container {
+        display: inline-block;
+        margin-right: 20px;
+        margin-bottom: 10px;
+        width: 100px;
+        vertical-align: top;
+    }
+    div.box {
+        width: 102px;
+        height: 52px;
+    }
+    canvas {
+        border: 1px solid black;
+        width: 100px;
+        height: 50px;
+    }
+</style>
+<body>
+    <b>CanvasRenderingContext2D.drawImage() should ignore the image's EXIF orientation if its style image-orientation is set to "none".</b>
+    <br>
+    <br>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas1"></canvas>
+        </div>
+        <br>Normal
+    </div>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas2"></canvas>
+        </div>
+        <br>Flipped horizontally
+    </div>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas3"></canvas>
+        </div>
+        <br>Rotated 180&deg;
+    </div>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas4"></canvas>
+        </div>
+        <br>Flipped vertically
+    </div>
+    <br>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas5"></canvas>
+        </div>
+        <br>Rotated 90&deg; CCW and flipped vertically
+    </div>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas6"></canvas>
+        </div>
+        <br>Rotated 90&deg; CCW
+    </div>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas7"></canvas>
+        </div>
+        <br>Rotated 90&deg; CW and flipped vertically
+    </div>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas8"></canvas>
+        </div>
+        <br>Rotated 90&deg; CW
+    </div>
+    <br>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas9"></canvas>
+        </div>
+        <br>Undefined (invalid value)
+    </div>
+    <script>
+        if (window.testRunner)
+            window.testRunner.waitUntilDone();
+
+        window._onload_ = function() {
+            var image = new Image;
+            image.src = ""
+            image.decode().then(() => {
+                let canvases = document.querySelectorAll("canvas");
+                for (const canvas of canvases) {
+                    canvas.width = canvas.offsetWidth - 2;
+                    canvas.height = canvas.offsetHeight - 2;
+                    let context = canvas.getContext("2d");
+                    context.drawImage(image, 0, 0, canvas.width, canvas.height);
+                }
+                if (window.testRunner)
+                    window.testRunner.notifyDone();
+            });
+        }
+    </script>
+</body>

Added: trunk/LayoutTests/fast/images/image-orientation-none-canvas.html (0 => 259567)


--- trunk/LayoutTests/fast/images/image-orientation-none-canvas.html	                        (rev 0)
+++ trunk/LayoutTests/fast/images/image-orientation-none-canvas.html	2020-04-06 08:03:17 UTC (rev 259567)
@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<style>
+    div.container {
+        display: inline-block;
+        margin-right: 20px;
+        margin-bottom: 10px;
+        width: 100px;
+        vertical-align: top;
+    }
+    div.box {
+        width: 102px;
+        height: 52px;
+    }
+    canvas {
+        border: 1px solid black;
+        width: 100px;
+        height: 50px;
+    }
+</style>
+<body>
+    <b>CanvasRenderingContext2D.drawImage() should ignore the image's EXIF orientation if its style image-orientation is set to "none".</b>
+    <br>
+    <br>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas1"></canvas>
+        </div>
+        <br>Normal
+    </div>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas2"></canvas>
+        </div>
+        <br>Flipped horizontally
+    </div>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas3"></canvas>
+        </div>
+        <br>Rotated 180&deg;
+    </div>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas4"></canvas>
+        </div>
+        <br>Flipped vertically
+    </div>
+    <br>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas5"></canvas>
+        </div>
+        <br>Rotated 90&deg; CCW and flipped vertically
+    </div>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas6"></canvas>
+        </div>
+        <br>Rotated 90&deg; CCW
+    </div>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas7"></canvas>
+        </div>
+        <br>Rotated 90&deg; CW and flipped vertically
+    </div>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas8"></canvas>
+        </div>
+        <br>Rotated 90&deg; CW
+    </div>
+    <br>
+    <div class ="container">
+        <div class ="box">
+            <canvas id="canvas9"></canvas>
+        </div>
+        <br>Undefined (invalid value)
+    </div>
+    <script>
+        if (window.testRunner)
+            window.testRunner.waitUntilDone();
+
+        window._onload_ = function() {
+            var names = [
+                { resource: "resources/exif-orientation-1-ul.jpg",  id : "canvas1" },
+                { resource: "resources/exif-orientation-2-ur.jpg",  id : "canvas2" },
+                { resource: "resources/exif-orientation-3-lr.jpg",  id : "canvas3" },
+                { resource: "resources/exif-orientation-4-lol.jpg", id : "canvas4" },
+                { resource: "resources/exif-orientation-5-lu.jpg",  id : "canvas5" },
+                { resource: "resources/exif-orientation-6-ru.jpg",  id : "canvas6" },
+                { resource: "resources/exif-orientation-7-rl.jpg",  id : "canvas7" },
+                { resource: "resources/exif-orientation-8-llo.jpg", id : "canvas8" },
+                { resource: "resources/exif-orientation-9-u.jpg",   id : "canvas9" }
+            ];
+
+            var drawCount = 0;
+
+            names.forEach(function(name) {
+                var image = new Image;
+                image.style.imageOrientation = "none";
+                image.style.display = "none";
+                image.src = ""
+                document.body.appendChild(image);
+                image.decode().then(() => {
+                    let canvas = document.getElementById(name.id);
+                    canvas.width = canvas.offsetWidth - 2;
+                    canvas.height = canvas.offsetHeight - 2;
+                    let context = canvas.getContext("2d");
+                    context.drawImage(image, 0, 0, canvas.width, canvas.height);
+                    if (++drawCount == names.length) {
+                        if (window.testRunner)
+                            window.testRunner.notifyDone();
+                    }
+                });
+            });
+        }
+    </script>
+</body>

Modified: trunk/Source/WebCore/ChangeLog (259566 => 259567)


--- trunk/Source/WebCore/ChangeLog	2020-04-06 06:04:44 UTC (rev 259566)
+++ trunk/Source/WebCore/ChangeLog	2020-04-06 08:03:17 UTC (rev 259567)
@@ -1,3 +1,20 @@
+2020-04-06  Said Abou-Hallawa  <sabouhall...@apple.com>
+
+        CanvasRenderingContext2D.drawImage should ignore the EXIF orientation if the image-orientation is none
+        https://bugs.webkit.org/show_bug.cgi?id=209849
+
+        Reviewed by Darin Adler.
+
+        drawImage() will get the image-orientation of the HTMLImageElement from
+        its computed style. This will be passed to GraphicsContext::drawImage()
+        in the ImagePaintingOptions. Previously we were passing FromImage always.
+
+        Test: fast/images/image-orientation-none-canvas.html
+
+        * html/canvas/CanvasRenderingContext2DBase.cpp:
+        (WebCore::CanvasRenderingContext2DBase::drawImage):
+        * html/canvas/CanvasRenderingContext2DBase.h:
+
 2020-04-05  Rob Buis  <rb...@igalia.com>
 
         Remove code that has no effect from loadURL

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp (259566 => 259567)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp	2020-04-06 06:04:44 UTC (rev 259566)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp	2020-04-06 08:03:17 UTC (rev 259567)
@@ -1464,8 +1464,12 @@
         return { };
     FloatRect imageRect = FloatRect(FloatPoint(), size(imageElement, ImageSizeType::BeforeDevicePixelRatio));
 
-    auto result = drawImage(imageElement.document(), imageElement.cachedImage(), imageElement.renderer(), imageRect, srcRect, dstRect, op, blendMode);
+    auto orientation = ImageOrientation::FromImage;
+    if (auto* computedStyle = imageElement.computedStyle())
+        orientation = computedStyle->imageOrientation();
 
+    auto result = drawImage(imageElement.document(), imageElement.cachedImage(), imageElement.renderer(), imageRect, srcRect, dstRect, op, blendMode, orientation);
+
     if (!result.hasException())
         checkOrigin(&imageElement);
     return result;
@@ -1487,7 +1491,7 @@
 }
 #endif
 
-ExceptionOr<void> CanvasRenderingContext2DBase::drawImage(Document& document, CachedImage* cachedImage, const RenderObject* renderer, const FloatRect& imageRect, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, const BlendMode& blendMode)
+ExceptionOr<void> CanvasRenderingContext2DBase::drawImage(Document& document, CachedImage* cachedImage, const RenderObject* renderer, const FloatRect& imageRect, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, const BlendMode& blendMode, ImageOrientation orientation)
 {
     if (!std::isfinite(dstRect.x()) || !std::isfinite(dstRect.y()) || !std::isfinite(dstRect.width()) || !std::isfinite(dstRect.height())
         || !std::isfinite(srcRect.x()) || !std::isfinite(srcRect.y()) || !std::isfinite(srcRect.width()) || !std::isfinite(srcRect.height()))
@@ -1543,7 +1547,7 @@
         downcast<BitmapImage>(*image).updateFromSettings(document.settings());
     }
 
-    ImagePaintingOptions options = { op, blendMode, ImageOrientation::FromImage };
+    ImagePaintingOptions options = { op, blendMode, orientation };
 
     if (rectContainsCanvas(normalizedDstRect)) {
         c->drawImage(*image, normalizedDstRect, normalizedSrcRect, options);

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h (259566 => 259567)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h	2020-04-06 06:04:44 UTC (rev 259566)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h	2020-04-06 08:03:17 UTC (rev 259567)
@@ -333,7 +333,7 @@
     ExceptionOr<void> drawImage(HTMLImageElement&, const FloatRect& srcRect, const FloatRect& dstRect);
     ExceptionOr<void> drawImage(HTMLImageElement&, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator&, const BlendMode&);
     ExceptionOr<void> drawImage(CanvasBase&, const FloatRect& srcRect, const FloatRect& dstRect);
-    ExceptionOr<void> drawImage(Document&, CachedImage*, const RenderObject*, const FloatRect& imageRect, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator&, const BlendMode&);
+    ExceptionOr<void> drawImage(Document&, CachedImage*, const RenderObject*, const FloatRect& imageRect, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator&, const BlendMode&, ImageOrientation = ImageOrientation::FromImage);
 #if ENABLE(VIDEO)
     ExceptionOr<void> drawImage(HTMLVideoElement&, const FloatRect& srcRect, const FloatRect& dstRect);
 #endif
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to