Add autodetection of image orientation from EXIF information
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 6 Apr 2012 20:02:59 +0000 (20:02 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 6 Apr 2012 20:02:59 +0000 (20:02 +0000)
https://bugs.webkit.org/show_bug.cgi?id=19688
<rdar://problem/4126979> and <rdar://problem/11091578>

Original patch by David Carson and Eric Seidel.

Reviewed by Simon Fraser.

Add support for respecting EXIF image orientation, enabled by default for ImageDocuments.
The setting shouldRespectImageOrientation causes orientation to take effect for any image included via <img>.

Test: fast/images/exif-orientation.html, fast/images/exif-orientation-css.html

File list truncated because it's very long.

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

76 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/images/exif-orientation-css.html [new file with mode: 0644]
LayoutTests/fast/images/exif-orientation.html [new file with mode: 0644]
LayoutTests/fast/images/resources/exif-orientation-1-ul.jpg [new file with mode: 0644]
LayoutTests/fast/images/resources/exif-orientation-2-ur.jpg [new file with mode: 0644]
LayoutTests/fast/images/resources/exif-orientation-3-lr.jpg [new file with mode: 0644]
LayoutTests/fast/images/resources/exif-orientation-4-lol.jpg [new file with mode: 0644]
LayoutTests/fast/images/resources/exif-orientation-5-lu.jpg [new file with mode: 0644]
LayoutTests/fast/images/resources/exif-orientation-6-ru.jpg [new file with mode: 0644]
LayoutTests/fast/images/resources/exif-orientation-7-rl.jpg [new file with mode: 0644]
LayoutTests/fast/images/resources/exif-orientation-8-llo.jpg [new file with mode: 0644]
LayoutTests/fast/images/resources/exif-orientation-9-u.jpg [new file with mode: 0644]
LayoutTests/platform/chromium/test_expectations.txt
LayoutTests/platform/efl/Skipped
LayoutTests/platform/gtk/Skipped
LayoutTests/platform/mac/fast/images/exif-orientation-css-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/fast/images/exif-orientation-css-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/fast/images/exif-orientation-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/fast/images/exif-orientation-expected.txt [new file with mode: 0644]
LayoutTests/platform/qt/Skipped
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/Target.pri
Source/WebCore/WebCore.exp.in
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/html/HTMLCanvasElement.cpp
Source/WebCore/loader/cache/CachedImage.cpp
Source/WebCore/page/DragController.cpp
Source/WebCore/page/Frame.cpp
Source/WebCore/page/Settings.h
Source/WebCore/platform/DragImage.h
Source/WebCore/platform/blackberry/DragImageBlackBerry.cpp
Source/WebCore/platform/chromium/DragImageChromiumMac.cpp
Source/WebCore/platform/chromium/DragImageChromiumSkia.cpp
Source/WebCore/platform/efl/DragImageEfl.cpp
Source/WebCore/platform/graphics/BitmapImage.cpp
Source/WebCore/platform/graphics/BitmapImage.h
Source/WebCore/platform/graphics/GraphicsContext.cpp
Source/WebCore/platform/graphics/GraphicsContext.h
Source/WebCore/platform/graphics/ImageOrientation.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/ImageOrientation.h [new file with mode: 0644]
Source/WebCore/platform/graphics/ImageSource.cpp
Source/WebCore/platform/graphics/ImageSource.h
Source/WebCore/platform/graphics/blackberry/GraphicsContext3DBlackBerry.cpp
Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
Source/WebCore/platform/graphics/cg/ImageCG.cpp
Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp
Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
Source/WebCore/platform/graphics/wince/ImageBufferWinCE.cpp
Source/WebCore/platform/graphics/wx/ImageBufferWx.cpp
Source/WebCore/platform/gtk/DragImageGtk.cpp
Source/WebCore/platform/mac/DragImageMac.mm
Source/WebCore/platform/qt/DragImageQt.cpp
Source/WebCore/platform/win/DragImageCGWin.cpp
Source/WebCore/platform/win/DragImageCairoWin.cpp
Source/WebCore/platform/wince/DragImageWinCE.cpp
Source/WebCore/platform/wx/DragImageWx.cpp
Source/WebCore/rendering/RenderImage.cpp
Source/WebCore/rendering/RenderObject.cpp
Source/WebCore/rendering/RenderObject.h
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebPreferenceKeysPrivate.h
Source/WebKit/mac/WebView/WebPreferences.mm
Source/WebKit/mac/WebView/WebPreferencesPrivate.h
Source/WebKit/mac/WebView/WebView.mm
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/WebPreferencesStore.h
Source/WebKit2/UIProcess/API/C/WKPreferences.cpp
Source/WebKit2/UIProcess/API/C/WKPreferences.h
Source/WebKit2/WebProcess/WebPage/WebPage.cpp

index 62dc9eb..b77a50d 100644 (file)
@@ -1,3 +1,32 @@
+2012-04-06  Tim Horton  <timothy_horton@apple.com>
+
+        Add autodetection of image orientation from EXIF information
+        https://bugs.webkit.org/show_bug.cgi?id=19688
+        <rdar://problem/4126979> and <rdar://problem/11091578>
+
+        Original patch by David Carson and Eric Seidel.
+
+        Reviewed by Simon Fraser.
+
+        Add a test ensuring that images in <img> respect their embedded EXIF orientation when the setting is enabled.
+        Add a test ensuring that images used via CSS's content property do not respect their embedded EXIF orientation.
+
+        * fast/images/exif-orientation.html: Added.
+        * fast/images/exif-orientation-css.html: Added.
+        * fast/images/resources/exif-orientation-1-ul.jpg: Added.
+        * fast/images/resources/exif-orientation-2-ur.jpg: Added.
+        * fast/images/resources/exif-orientation-3-lr.jpg: Added.
+        * fast/images/resources/exif-orientation-4-lol.jpg: Added.
+        * fast/images/resources/exif-orientation-5-lu.jpg: Added.
+        * fast/images/resources/exif-orientation-6-ru.jpg: Added.
+        * fast/images/resources/exif-orientation-7-rl.jpg: Added.
+        * fast/images/resources/exif-orientation-8-llo.jpg: Added.
+        * fast/images/resources/exif-orientation-9-u.jpg: Added.
+        * platform/mac/fast/images/exif-orientation-expected.png: Added.
+        * platform/mac/fast/images/exif-orientation-expected.txt: Added.
+        * platform/mac/fast/images/exif-orientation-css-expected.png: Added.
+        * platform/mac/fast/images/exif-orientation-css-expected.txt: Added.
+
 2012-04-06  Joshua Bell  <jsbell@chromium.org>
 
         IndexedDB: Race condition in layout test logging from window and worker
diff --git a/LayoutTests/fast/images/exif-orientation-css.html b/LayoutTests/fast/images/exif-orientation-css.html
new file mode 100644 (file)
index 0000000..838f6a1
--- /dev/null
@@ -0,0 +1,55 @@
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.overridePreference('WebKitShouldRespectImageOrientation', 1);
+    layoutTestController.dumpAsText(1);
+}
+
+function log(str) {
+    var li = document.createElement("li");
+    li.appendChild(document.createTextNode(str));
+    var console = document.getElementById("console");
+    console.appendChild(li);
+}
+
+function imageSize(el) {
+    var computedStyle = window.getComputedStyle(el);
+    return computedStyle.width + " by " + computedStyle.height;
+}
+
+
+function load() {
+    for(var i = 1; i <= 13; i++)
+        log("img" + i + " size = " + imageSize(document.getElementById("img" + i)))
+}
+
+</script>
+<style>
+div.image { display: inline-block; border: 1px solid black; }
+div.container { display: inline-block; margin-right: 20px; margin-bottom: 10px; width: 100px; vertical-align: top; }
+img { width: 100px; height: 100px; background-repeat: no-repeat; }
+</style>
+</head>
+<body onload="load()">
+<b>None of the images should be rotated. This test is only valid when run with layoutTestController (or with WebKitShouldRespectImageOrientation manually set to true).</b><br><br>
+<div class="container"><div class="image" id="img1" style="content: url(resources/exif-orientation-1-ul.jpg)"></div><br>Normal</div>
+<div class="container"><div class="image" id="img2" style="content: url(resources/exif-orientation-2-ur.jpg)"></div><br>Flipped horizontally</div>
+<div class="container"><div class="image" id="img3" style="content: url(resources/exif-orientation-3-lr.jpg)"></div><br>Rotated 180&deg;</div>
+<div class="container"><div class="image" id="img4" style="content: url(resources/exif-orientation-4-lol.jpg)"></div><br>Flipped vertically</div>
+<br>
+<div class="container"><div class="image" id="img5" style="content: url(resources/exif-orientation-5-lu.jpg)"></div><br>Rotated 90&deg; CCW and flipped vertically</div>
+<div class="container"><div class="image" id="img6" style="content: url(resources/exif-orientation-6-ru.jpg)"></div><br>Rotated 90&deg; CCW</div>
+<div class="container"><div class="image" id="img7" style="content: url(resources/exif-orientation-7-rl.jpg)"></div><br>Rotated 90&deg; CW and flipped vertically</div>
+<div class="container"><div class="image" id="img8" style="content: url(resources/exif-orientation-8-llo.jpg)"></div><br>Rotated 90&deg; CW</div>
+<br>
+<div class="container"><img id="img9" style="background-image: url(resources/exif-orientation-5-lu.jpg)"></img><br>Rotated 90&deg; CCW and flipped vertically</div>
+<div class="container"><img id="img10" style="background-image: url(resources/exif-orientation-6-ru.jpg)"></img><br>Rotated 90&deg; CCW</div>
+<div class="container"><img id="img11" style="background-image: url(resources/exif-orientation-7-rl.jpg)"></img><br>Rotated 90&deg; CW and flipped vertically</div>
+<div class="container"><img id="img12" style="background-image: url(resources/exif-orientation-8-llo.jpg)"></img><br>Rotated 90&deg; CW</div>
+<br>
+<div class="container"><div class="image" id="img13" style="content: url(resources/exif-orientation-9-u.jpg)"></div><br>Undefined (invalid value)</div>
+<br>
+<ul id="console"></ul>
+</body>
+</html>
diff --git a/LayoutTests/fast/images/exif-orientation.html b/LayoutTests/fast/images/exif-orientation.html
new file mode 100644 (file)
index 0000000..4a8c425
--- /dev/null
@@ -0,0 +1,49 @@
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.overridePreference('WebKitShouldRespectImageOrientation', 1);
+    layoutTestController.dumpAsText(1);
+}
+
+function log(str) {
+    var li = document.createElement("li");
+    li.appendChild(document.createTextNode(str));
+    var console = document.getElementById("console");
+    console.appendChild(li);
+}
+
+function imageSize(el) {
+    var computedStyle = window.getComputedStyle(el);
+    return computedStyle.width + " by " + computedStyle.height;
+}
+
+
+function load() {
+    for(var i = 1; i <= 9; i++)
+        log("img" + i + " size = " + imageSize(document.getElementById("img" + i)))
+}
+
+</script>
+<style>
+img { border: 1px solid black; }
+div { display: inline-block; margin-right: 20px; margin-bottom: 10px; width: 100px; vertical-align: top; }
+</style>
+</head>
+<body onload="load()">
+<b>The images should be rotated respecting their EXIF orientation. This test can only be run with layoutTestController (or by manually setting WebKitShouldRespectImageOrientation to true).</b><br><br>
+<div><img id="img1" src="resources/exif-orientation-1-ul.jpg"><br>Normal</div>
+<div><img id="img2" src="resources/exif-orientation-2-ur.jpg"><br>Flipped horizontally</div>
+<div><img id="img3" src="resources/exif-orientation-3-lr.jpg"><br>Rotated 180&deg;</div>
+<div><img id="img4" src="resources/exif-orientation-4-lol.jpg"><br>Flipped vertically</div>
+<br>
+<div><img id="img5" src="resources/exif-orientation-5-lu.jpg"><br>Rotated 90&deg; CCW and flipped vertically</div>
+<div><img id="img6" src="resources/exif-orientation-6-ru.jpg"><br>Rotated 90&deg; CCW</div>
+<div><img id="img7" src="resources/exif-orientation-7-rl.jpg"><br>Rotated 90&deg; CW and flipped vertically </div>
+<div><img id="img8" src="resources/exif-orientation-8-llo.jpg"><br>Rotated 90&deg; CW</div>
+<br>
+<div><img id="img9" src="resources/exif-orientation-9-u.jpg"><br>Undefined (invalid value)</div>
+<br>
+<ul id="console"></ul>
+</body>
+</html>
diff --git a/LayoutTests/fast/images/resources/exif-orientation-1-ul.jpg b/LayoutTests/fast/images/resources/exif-orientation-1-ul.jpg
new file mode 100644 (file)
index 0000000..6357ff0
Binary files /dev/null and b/LayoutTests/fast/images/resources/exif-orientation-1-ul.jpg differ
diff --git a/LayoutTests/fast/images/resources/exif-orientation-2-ur.jpg b/LayoutTests/fast/images/resources/exif-orientation-2-ur.jpg
new file mode 100644 (file)
index 0000000..0f260e3
Binary files /dev/null and b/LayoutTests/fast/images/resources/exif-orientation-2-ur.jpg differ
diff --git a/LayoutTests/fast/images/resources/exif-orientation-3-lr.jpg b/LayoutTests/fast/images/resources/exif-orientation-3-lr.jpg
new file mode 100644 (file)
index 0000000..b50b430
Binary files /dev/null and b/LayoutTests/fast/images/resources/exif-orientation-3-lr.jpg differ
diff --git a/LayoutTests/fast/images/resources/exif-orientation-4-lol.jpg b/LayoutTests/fast/images/resources/exif-orientation-4-lol.jpg
new file mode 100644 (file)
index 0000000..486dd06
Binary files /dev/null and b/LayoutTests/fast/images/resources/exif-orientation-4-lol.jpg differ
diff --git a/LayoutTests/fast/images/resources/exif-orientation-5-lu.jpg b/LayoutTests/fast/images/resources/exif-orientation-5-lu.jpg
new file mode 100644 (file)
index 0000000..7689d63
Binary files /dev/null and b/LayoutTests/fast/images/resources/exif-orientation-5-lu.jpg differ
diff --git a/LayoutTests/fast/images/resources/exif-orientation-6-ru.jpg b/LayoutTests/fast/images/resources/exif-orientation-6-ru.jpg
new file mode 100644 (file)
index 0000000..a51a126
Binary files /dev/null and b/LayoutTests/fast/images/resources/exif-orientation-6-ru.jpg differ
diff --git a/LayoutTests/fast/images/resources/exif-orientation-7-rl.jpg b/LayoutTests/fast/images/resources/exif-orientation-7-rl.jpg
new file mode 100644 (file)
index 0000000..5c1c15d
Binary files /dev/null and b/LayoutTests/fast/images/resources/exif-orientation-7-rl.jpg differ
diff --git a/LayoutTests/fast/images/resources/exif-orientation-8-llo.jpg b/LayoutTests/fast/images/resources/exif-orientation-8-llo.jpg
new file mode 100644 (file)
index 0000000..34b895f
Binary files /dev/null and b/LayoutTests/fast/images/resources/exif-orientation-8-llo.jpg differ
diff --git a/LayoutTests/fast/images/resources/exif-orientation-9-u.jpg b/LayoutTests/fast/images/resources/exif-orientation-9-u.jpg
new file mode 100644 (file)
index 0000000..76e9d90
Binary files /dev/null and b/LayoutTests/fast/images/resources/exif-orientation-9-u.jpg differ
index 2c19fa8..4e3841e 100644 (file)
@@ -3865,3 +3865,7 @@ BUGWK83183 MAC : svg/as-image/animated-svg-as-image-no-fixed-intrinsic-size.html
 BUGWK83185 MAC DEBUG : fast/writing-mode/relative-positioning-percentages.html = CRASH
 BUGWK83219 LION : fonts/cursive.html = PASS IMAGE+TEXT
 BUGWK83324 WIN DEBUG : fast/js/cross-global-object-inline-global-var.html = PASS TEXT
+
+// EXIF orientation support has not yet been implemented for this platform
+BUGWK19688 SKIP : fast/images/exif-orientation.html = FAIL
+BUGWK19688 SKIP : fast/images/exif-orientation-css.html = FAIL
index c835d3e..3b8414c 100644 (file)
@@ -1002,6 +1002,11 @@ editing/pasteboard/drag-files-to-editable-element.html
 # http://webkit.org/b/79604
 fast/mutation/database-callback-delivery.html
 
+# EXIF orientation support has not yet been implemented for this platform
+# http://webkit.org/b/19688
+fast/images/exif-orientation.html
+fast/images/exif-orientation-css.html
+
 # --------------------------------
 # Tests which are expected to fail
 # --------------------------------
index 14062be..c72830a 100644 (file)
@@ -422,6 +422,11 @@ batterystatus
 #Network Information API support not yet. http://webkit.org/b/73528
 networkinformation
 
+# EXIF orientation support has not yet been implemented for this platform
+# http://webkit.org/b/19688
+fast/images/exif-orientation.html
+fast/images/exif-orientation-css.html
+
 ###############################################################################
 # TESTS FAILING
 ###############################################################################
diff --git a/LayoutTests/platform/mac/fast/images/exif-orientation-css-expected.png b/LayoutTests/platform/mac/fast/images/exif-orientation-css-expected.png
new file mode 100644 (file)
index 0000000..6d8e90a
Binary files /dev/null and b/LayoutTests/platform/mac/fast/images/exif-orientation-css-expected.png differ
diff --git a/LayoutTests/platform/mac/fast/images/exif-orientation-css-expected.txt b/LayoutTests/platform/mac/fast/images/exif-orientation-css-expected.txt
new file mode 100644 (file)
index 0000000..b26cf8a
--- /dev/null
@@ -0,0 +1,32 @@
+None of the images should be rotated. This test is only valid when run with layoutTestController (or with WebKitShouldRespectImageOrientation manually set to true).
+
+
+Normal 
+Flipped horizontally 
+Rotated 180° 
+Flipped vertically 
+
+Rotated 90° CCW and flipped vertically 
+Rotated 90° CCW 
+Rotated 90° CW and flipped vertically 
+Rotated 90° CW 
+
+Rotated 90° CCW and flipped vertically 
+Rotated 90° CCW 
+Rotated 90° CW and flipped vertically 
+Rotated 90° CW 
+
+Undefined (invalid value) 
+img1 size = 100px by 50px
+img2 size = 100px by 50px
+img3 size = 100px by 50px
+img4 size = 100px by 50px
+img5 size = 100px by 50px
+img6 size = 100px by 50px
+img7 size = 100px by 50px
+img8 size = 100px by 50px
+img9 size = 100px by 100px
+img10 size = 100px by 100px
+img11 size = 100px by 100px
+img12 size = 100px by 100px
+img13 size = 100px by 50px
diff --git a/LayoutTests/platform/mac/fast/images/exif-orientation-expected.png b/LayoutTests/platform/mac/fast/images/exif-orientation-expected.png
new file mode 100644 (file)
index 0000000..a3143c4
Binary files /dev/null and b/LayoutTests/platform/mac/fast/images/exif-orientation-expected.png differ
diff --git a/LayoutTests/platform/mac/fast/images/exif-orientation-expected.txt b/LayoutTests/platform/mac/fast/images/exif-orientation-expected.txt
new file mode 100644 (file)
index 0000000..1d06668
--- /dev/null
@@ -0,0 +1,23 @@
+The images should be rotated respecting their EXIF orientation. This test can only be run with layoutTestController (or by manually setting WebKitShouldRespectImageOrientation to true).
+
+
+Normal 
+Flipped horizontally 
+Rotated 180° 
+Flipped vertically 
+
+Rotated 90° CCW and flipped vertically 
+Rotated 90° CCW 
+Rotated 90° CW and flipped vertically  
+Rotated 90° CW 
+
+Undefined (invalid value) 
+img1 size = 100px by 50px
+img2 size = 100px by 50px
+img3 size = 100px by 50px
+img4 size = 100px by 50px
+img5 size = 50px by 100px
+img6 size = 50px by 100px
+img7 size = 50px by 100px
+img8 size = 50px by 100px
+img9 size = 100px by 50px
index 1ab531b..ac77596 100644 (file)
@@ -396,6 +396,11 @@ batterystatus
 # Network Information API is not supported yet. http://webkit.org/b/73528
 networkinformation
 
+# EXIF orientation support has not yet been implemented for this platform
+# http://webkit.org/b/19688
+fast/images/exif-orientation.html
+fast/images/exif-orientation-css.html
+
 # =========================================================================== #
 #       Drag and Drop Support in DRT.                                         #
 # =========================================================================== #
index e4e9b66..580ece7 100644 (file)
@@ -1146,6 +1146,7 @@ SET(WebCore_SOURCES
     platform/graphics/GraphicsTypes.cpp
     platform/graphics/Image.cpp
     platform/graphics/ImageBuffer.cpp
+    platform/graphics/ImageOrientation.cpp
     platform/graphics/IntRect.cpp
     platform/graphics/Path.cpp
     platform/graphics/PathTraversalState.cpp
index 3a80ba3..f323a58 100644 (file)
@@ -1,3 +1,79 @@
+2012-04-06  Tim Horton  <timothy_horton@apple.com>
+
+        Add autodetection of image orientation from EXIF information
+        https://bugs.webkit.org/show_bug.cgi?id=19688
+        <rdar://problem/4126979> and <rdar://problem/11091578>
+
+        Original patch by David Carson and Eric Seidel.
+
+        Reviewed by Simon Fraser.
+
+        Add support for respecting EXIF image orientation, enabled by default for ImageDocuments.
+        The setting shouldRespectImageOrientation causes orientation to take effect for any image included via <img>.
+
+        Test: fast/images/exif-orientation.html, fast/images/exif-orientation-css.html
+
+        * WebCore.xcodeproj/project.pbxproj: Add ImageOrientation.{cpp, h}
+        * loader/cache/CachedImage.cpp:
+        (WebCore::CachedImage::imageForRenderer): Plumb setting down from RenderObject into Image.
+        (WebCore::CachedImage::imageSizeForRenderer):
+        * page/Settings.h:
+        (WebCore::Settings::setShouldRespectImageOrientation):
+        (WebCore::Settings::shouldRespectImageOrientation):
+        (Settings):
+        * platform/graphics/BitmapImage.cpp:
+        (WebCore::BitmapImage::cacheFrame):
+        (WebCore::BitmapImage::size):
+        (WebCore::BitmapImage::sizeRespectingOrientation):
+        (WebCore):
+        (WebCore::BitmapImage::ensureFrameIsCached):
+        (WebCore::BitmapImage::frameAtIndex):
+        (WebCore::BitmapImage::frameIsCompleteAtIndex):
+        (WebCore::BitmapImage::frameDurationAtIndex):
+        (WebCore::BitmapImage::frameHasAlphaAtIndex):
+        (WebCore::BitmapImage::frameOrientationAtIndex):
+        * platform/graphics/BitmapImage.h:
+        (WebCore::FrameData::FrameData):
+        (FrameData):
+        (BitmapImage):
+        * platform/graphics/GraphicsContext.h:
+        (GraphicsContext):
+        * platform/graphics/ImageOrientation.cpp: Added.
+        (WebCore):
+        (WebCore::ImageOrientation::transformFromDefault):
+        * platform/graphics/ImageOrientation.h: Added.
+        (WebCore):
+        (ImageOrientation):
+        (WebCore::ImageOrientation::ImageOrientation):
+        (WebCore::ImageOrientation::usesWidthAsHeight):
+        (WebCore::ImageOrientation::fromEXIFValue):
+        (WebCore::ImageOrientation::operator==):
+        (WebCore::ImageOrientation::operator!=):
+        * platform/graphics/ImageSource.cpp:
+        (WebCore::ImageSource::orientationAtIndex):
+        (WebCore):
+        * platform/graphics/ImageSource.h:
+        (WebCore):
+        * platform/graphics/cg/GraphicsContextCG.cpp:
+        (WebCore::GraphicsContext::drawNativeImage): Transform the image while drawing if its orientation requires it.
+        * platform/graphics/cg/ImageBufferCG.cpp:
+        (WebCore::ImageBuffer::draw):
+        * platform/graphics/cg/ImageCG.cpp:
+        (WebCore::FrameData::clear):
+        (WebCore::BitmapImage::BitmapImage):
+        (WebCore::BitmapImage::draw):
+        * platform/graphics/cg/ImageSourceCG.cpp:
+        (WebCore::imageSourceOptions): Don't use SkipMetaData on Lion/Snow Leopard, as it prevents us from retrieving orientation data.
+        (WebCore::ImageSource::frameSizeAtIndex): Adjust the image's size based on its orientation.
+        (WebCore):
+        (WebCore::ImageSource::orientationAtIndex):
+        (WebCore::ImageSource::size):
+        * platform/graphics/mac/DragImageMac.mm:
+        (createDragImageFromImage): Create scaled copy of image for drag image if we're respecting orientation and it is non-default.
+        * rendering/RenderObject.h:
+        (RenderObject):
+        (WebCore::RenderObject::shouldRespectImageOrientation):
+
 2012-04-06  Levi Weintraub  <leviw@chromium.org>
 
         Correct LayoutUnit usgae in RenderThemeQt and RenderThemeQStyle
index 62250cb..c75d0a2 100644 (file)
@@ -3238,6 +3238,8 @@ webcore_sources += \
        Source/WebCore/platform/graphics/Image.cpp \
        Source/WebCore/platform/graphics/Image.h \
        Source/WebCore/platform/graphics/ImageObserver.h \
+       Source/WebCore/platform/graphics/ImageOrientation.cpp \
+       Source/WebCore/platform/graphics/ImageOrientation.h \
        Source/WebCore/platform/graphics/ImageSource.cpp \
        Source/WebCore/platform/graphics/ImageSource.h \
        Source/WebCore/platform/graphics/IntPoint.h \
index 16e65cb..cd7e572 100644 (file)
@@ -1093,6 +1093,7 @@ SOURCES += \
     platform/graphics/GraphicsTypes.cpp \
     platform/graphics/Image.cpp \
     platform/graphics/ImageBuffer.cpp \
+    platform/graphics/ImageOrientation.cpp \
     platform/graphics/ImageSource.cpp \
     platform/graphics/IntRect.cpp \
     platform/graphics/Path.cpp \
@@ -2224,6 +2225,7 @@ HEADERS += \
     platform/graphics/GraphicsTypes.h \
     platform/graphics/GraphicsTypes3D.h \
     platform/graphics/Image.h \
+    platform/graphics/ImageOrientation.h \
     platform/graphics/ImageSource.h \
     platform/graphics/IntPoint.h \
     platform/graphics/IntPointHash.h \
index e83d92c..f203c83 100644 (file)
@@ -446,7 +446,7 @@ __ZN7WebCore15GraphicsContext8fillPathERKNS_4PathE
 __ZN7WebCore15GraphicsContext8fillRectERKNS_9FloatRectE
 __ZN7WebCore15GraphicsContext8fillRectERKNS_9FloatRectERKNS_5ColorENS_10ColorSpaceE
 __ZN7WebCore15GraphicsContext9clearRectERKNS_9FloatRectE
-__ZN7WebCore15GraphicsContext9drawImageEPNS_5ImageENS_10ColorSpaceERKNS_8IntPointENS_17CompositeOperatorE
+__ZN7WebCore15GraphicsContext9drawImageEPNS_5ImageENS_10ColorSpaceERKNS_8IntPointENS_17CompositeOperatorENS_27RespectImageOrientationEnumE
 __ZN7WebCore15GraphicsContext9setShadowERKNS_9FloatSizeEfRKNS_5ColorENS_10ColorSpaceE
 __ZN7WebCore15GraphicsContext9translateEff
 __ZN7WebCore15GraphicsContextC1EP9CGContext
index 34f628d..0a96e32 100644 (file)
             'platform/graphics/ImageBuffer.h',
             'platform/graphics/ImageBufferData.h',
             'platform/graphics/ImageObserver.h',
+            'platform/graphics/ImageOrientation.h',
             'platform/graphics/ImageSource.h',
             'platform/graphics/IntPoint.h',
             'platform/graphics/IntPointHash.h',
             'platform/graphics/GraphicsTypes.cpp',
             'platform/graphics/Image.cpp',
             'platform/graphics/ImageBuffer.cpp',
+            'platform/graphics/ImageOrientation.cpp',
             'platform/graphics/ImageSource.cpp',
             'platform/graphics/IntRect.cpp',
             'platform/graphics/MediaPlayer.cpp',
index e1e756d..6ea3425 100755 (executable)
                                        >
                                </File>
                                <File
+                                       RelativePath="..\platform\graphics\ImageOrientation.cpp"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\platform\graphics\ImageOrientation.h"
+                                       >
+                               </File>
+                               <File
                                        RelativePath="..\platform\graphics\ImageSource.cpp"
                                        >
                                        <FileConfiguration
index 16871c9..6d84249 100644 (file)
                2D481F02146B5C5500AA7834 /* CrossfadeGeneratedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D2FC0551460CD6F00263633 /* CrossfadeGeneratedImage.h */; };
                2D481F03146B5C6500AA7834 /* GeneratorGeneratedImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D2FC0561460CD6F00263633 /* GeneratorGeneratedImage.cpp */; };
                2D481F04146B5C6B00AA7834 /* GeneratorGeneratedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D2FC0571460CD6F00263633 /* GeneratorGeneratedImage.h */; };
+               2D5A592F152525230036EE51 /* ImageOrientation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8748D7412CC3F89001FBA41 /* ImageOrientation.cpp */; };
+               2D5A5931152525D00036EE51 /* ImageOrientation.h in Headers */ = {isa = PBXBuildFile; fileRef = A8748D6612CC3763001FBA41 /* ImageOrientation.h */; settings = {ATTRIBUTES = (Private, ); }; };
                2D8FEBDC143E3EF70072502B /* CSSCrossfadeValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D8FEBDA143E3EF70072502B /* CSSCrossfadeValue.cpp */; };
                2D8FEBDD143E3EF70072502B /* CSSCrossfadeValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D8FEBDB143E3EF70072502B /* CSSCrossfadeValue.h */; };
                2D9066060BE141D400956998 /* LayoutState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D9066040BE141D400956998 /* LayoutState.cpp */; };
                A871DFE00A15376B00B12A68 /* RenderWidget.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderWidget.h; sourceTree = "<group>"; };
                A871DFE10A15376B00B12A68 /* RenderWidget.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderWidget.cpp; sourceTree = "<group>"; };
                A8748BDF12CBF2DC001FBA41 /* HashTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HashTools.h; sourceTree = "<group>"; };
+               A8748D6612CC3763001FBA41 /* ImageOrientation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageOrientation.h; sourceTree = "<group>"; };
+               A8748D7412CC3F89001FBA41 /* ImageOrientation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageOrientation.cpp; sourceTree = "<group>"; };
                A883DF250F3D045D00F19BF6 /* VisibleSelection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VisibleSelection.cpp; sourceTree = "<group>"; };
                A883DF260F3D045D00F19BF6 /* VisibleSelection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VisibleSelection.h; sourceTree = "<group>"; };
                A886CDC214FBBAA300D279F4 /* WorkerContextWebSocket.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = WorkerContextWebSocket.idl; path = Modules/websockets/WorkerContextWebSocket.idl; sourceTree = "<group>"; };
                                501BAAA813950E2C00F7ACEB /* WindRule.h */,
                                379919941200DDF400EA041C /* WOFFFileFormat.cpp */,
                                379919951200DDF400EA041C /* WOFFFileFormat.h */,
+                               A8748D6612CC3763001FBA41 /* ImageOrientation.h */,
+                               A8748D7412CC3F89001FBA41 /* ImageOrientation.cpp */,
                        );
                        path = graphics;
                        sourceTree = "<group>";
                                49E912AD0EFAC906009D0CAF /* AnimationList.h in Headers */,
                                0F580FAF149800D400FB5BD8 /* AnimationUtilities.h in Headers */,
                                93309DD7099E64920056E581 /* AppendNodeCommand.h in Headers */,
+                               2D5A5931152525D00036EE51 /* ImageOrientation.h in Headers */,
                                1A8F6BBD0DB55CDC001DB794 /* ApplicationCache.h in Headers */,
                                1A8F6BBF0DB55CDC001DB794 /* ApplicationCacheGroup.h in Headers */,
                                24F54EAD101FE914000AE741 /* ApplicationCacheHost.h in Headers */,
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               2D5A592F152525230036EE51 /* ImageOrientation.cpp in Sources */,
                                97BC69DA1505F076001B74AC /* AbstractDatabase.cpp in Sources */,
                                41E1B1D00FF5986900576B3B /* AbstractWorker.cpp in Sources */,
                                0F29C16E1300C2E2002D794E /* AccessibilityAllInOne.cpp in Sources */,
index afb613a..7fc75ee 100644 (file)
@@ -331,7 +331,7 @@ void HTMLCanvasElement::paint(GraphicsContext* context, const LayoutRect& r, boo
         ImageBuffer* imageBuffer = buffer();
         if (imageBuffer) {
             if (m_presentedImage)
-                context->drawImage(m_presentedImage.get(), ColorSpaceDeviceRGB, pixelSnappedIntRect(r), CompositeSourceOver, useLowQualityScale);
+                context->drawImage(m_presentedImage.get(), ColorSpaceDeviceRGB, pixelSnappedIntRect(r), CompositeSourceOver, DoNotRespectImageOrientation, useLowQualityScale);
             else
                 context->drawImageBuffer(imageBuffer, ColorSpaceDeviceRGB, pixelSnappedIntRect(r), CompositeSourceOver, useLowQualityScale);
         }
index 10d7ad3..51f2f00 100644 (file)
@@ -241,7 +241,12 @@ IntSize CachedImage::imageSizeForRenderer(const RenderObject* renderer, float mu
     if (!m_image)
         return IntSize();
 
-    IntSize imageSize = m_image->size();
+    IntSize imageSize;
+
+    if (m_image->isBitmapImage() && (renderer && renderer->shouldRespectImageOrientation() == RespectImageOrientation))
+        imageSize = static_cast<BitmapImage*>(m_image.get())->sizeRespectingOrientation();
+    else
+        imageSize = m_image->size();
 
 #if ENABLE(SVG)
     if (m_image->isSVGImage()) {
@@ -251,8 +256,6 @@ IntSize CachedImage::imageSizeForRenderer(const RenderObject* renderer, float mu
             imageSize.setHeight(sizeAndZoom.size.height() / sizeAndZoom.zoom);
         }
     }
-#else
-    UNUSED_PARAM(renderer);
 #endif
 
     if (multiplier == 1.0f)
index cfdc9c5..3d2e337 100644 (file)
@@ -51,6 +51,7 @@
 #include "HitTestRequest.h"
 #include "HitTestResult.h"
 #include "Image.h"
+#include "ImageOrientation.h"
 #include "MoveSelectionCommand.h"
 #include "Node.h"
 #include "Page.h"
@@ -851,7 +852,7 @@ void DragController::doImageDrag(Element* element, const IntPoint& dragOrigin, c
 
     Image* image = getImage(element);
     if (image && image->size().height() * image->size().width() <= MaxOriginalImageArea
-        && (dragImage = createDragImageFromImage(image))) {
+        && (dragImage = createDragImageFromImage(image, element->renderer() ? element->renderer()->shouldRespectImageOrientation() : DoNotRespectImageOrientation))) {
         IntSize originalSize = rect.size();
         origin = rect.location();
 
index 49eface..56cd972 100644 (file)
@@ -1087,7 +1087,7 @@ DragImageRef Frame::nodeImage(Node* node)
     m_view->paintContents(buffer->context(), paintingRect);
 
     RefPtr<Image> image = buffer->copyImage();
-    return createDragImageFromImage(image.get());
+    return createDragImageFromImage(image.get(), renderer->shouldRespectImageOrientation());
 }
 
 DragImageRef Frame::dragImageForSelection()
index a02a236..d2949de 100644 (file)
@@ -549,6 +549,9 @@ namespace WebCore {
         void setThreadedAnimationEnabled(bool enabled) { m_threadedAnimationEnabled = enabled; }
         bool threadedAnimationEnabled() const { return m_threadedAnimationEnabled; }
 
+        void setShouldRespectImageOrientation(bool enabled) { m_shouldRespectImageOrientation = enabled; }
+        bool shouldRespectImageOrientation() const { return m_shouldRespectImageOrientation; }
+
     private:
         Settings(Page*);
 
@@ -703,6 +706,7 @@ namespace WebCore {
         bool m_touchEventEmulationEnabled : 1;
 #endif
         bool m_threadedAnimationEnabled : 1;
+        bool m_shouldRespectImageOrientation : 1;
 
         Timer<Settings> m_loadsImagesAutomaticallyTimer;
         void loadsImagesAutomaticallyTimerFired(Timer<Settings>*);
index a22db6a..dd970d2 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef DragImage_h
 #define DragImage_h
 
+#include "ImageOrientation.h"
 #include "IntSize.h"
 #include "FloatSize.h"
 #include <wtf/Forward.h>
@@ -81,7 +82,7 @@ namespace WebCore {
     DragImageRef scaleDragImage(DragImageRef, FloatSize scale);
     DragImageRef dissolveDragImageToFraction(DragImageRef image, float delta);
     
-    DragImageRef createDragImageFromImage(Image*);
+    DragImageRef createDragImageFromImage(Image*, RespectImageOrientationEnum = DoNotRespectImageOrientation);
     DragImageRef createDragImageForSelection(Frame*);    
     DragImageRef createDragImageIconForCachedImage(CachedImage*);
     DragImageRef createDragImageForLink(KURL&, const String& label, Frame*);
index 0bd29db..404e8f2 100644 (file)
@@ -26,7 +26,7 @@
 
 namespace WebCore {
 
-void* createDragImageFromImage(Image*)
+void* createDragImageFromImage(Image*, RespectImageOrientationEnum)
 {
     notImplemented();
     return 0;
index a0c2e20..e12780f 100644 (file)
@@ -98,7 +98,7 @@ DragImageRef dissolveDragImageToFraction(DragImageRef image, float delta)
     return dissolvedImage;
 }
 
-DragImageRef createDragImageFromImage(Image* image)
+DragImageRef createDragImageFromImage(Image* image, RespectImageOrientationEnum)
 {
     if (!image)
         return 0;
index 38a07f6..40f8925 100644 (file)
@@ -92,7 +92,7 @@ DragImageRef dissolveDragImageToFraction(DragImageRef image, float fraction)
     return image;
 }
 
-DragImageRef createDragImageFromImage(Image* image)
+DragImageRef createDragImageFromImage(Image* image, RespectImageOrientationEnum)
 {
     if (!image)
         return 0;
index 4b0f417..4c19da7 100644 (file)
@@ -50,7 +50,7 @@ DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
     return image;
 }
 
-DragImageRef createDragImageFromImage(Image*)
+DragImageRef createDragImageFromImage(Image*, RespectImageOrientationEnum)
 {
     notImplemented();
     return 0;
index 8cb3e1e..55a98c9 100644 (file)
@@ -139,6 +139,7 @@ void BitmapImage::cacheFrame(size_t index)
     if (numFrames == 1 && m_frames[index].m_frame)
         checkForSolidColor();
 
+    m_frames[index].m_orientation = m_source.orientationAtIndex(index);
     m_frames[index].m_haveMetadata = true;
     m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index);
     if (repetitionCount(false) != cAnimationNone)
@@ -182,12 +183,24 @@ IntSize BitmapImage::size() const
 {
     if (m_sizeAvailable && !m_haveSize) {
         m_size = m_source.size();
+        m_sizeRespectingOrientation = m_source.size(RespectImageOrientation);
         m_haveSize = true;
         didDecodeProperties();
     }
     return m_size;
 }
 
+IntSize BitmapImage::sizeRespectingOrientation() const
+{
+    if (m_sizeAvailable && !m_haveSize) {
+        m_size = m_source.size();
+        m_sizeRespectingOrientation = m_source.size(RespectImageOrientation);
+        m_haveSize = true;
+        didDecodeProperties();
+    }
+    return m_sizeRespectingOrientation;
+}
+
 IntSize BitmapImage::currentFrameSize() const
 {
     if (!m_currentFrame || m_hasUniformFrameSize)
@@ -268,36 +281,34 @@ bool BitmapImage::isSizeAvailable()
     return m_sizeAvailable;
 }
 
-NativeImagePtr BitmapImage::frameAtIndex(size_t index)
+bool BitmapImage::ensureFrameIsCached(size_t index)
 {
     if (index >= frameCount())
-        return 0;
+        return false;
 
     if (index >= m_frames.size() || !m_frames[index].m_frame)
         cacheFrame(index);
+    return true;
+}
 
+NativeImagePtr BitmapImage::frameAtIndex(size_t index)
+{
+    if (!ensureFrameIsCached(index))
+        return 0;
     return m_frames[index].m_frame;
 }
 
 bool BitmapImage::frameIsCompleteAtIndex(size_t index)
 {
-    if (index >= frameCount())
-        return true;
-
-    if (index >= m_frames.size() || !m_frames[index].m_haveMetadata)
-        cacheFrame(index);
-
+    if (!ensureFrameIsCached(index))
+        return true; // Why would an invalid index return true here?
     return m_frames[index].m_isComplete;
 }
 
 float BitmapImage::frameDurationAtIndex(size_t index)
 {
-    if (index >= frameCount())
+    if (!ensureFrameIsCached(index))
         return 0;
-
-    if (index >= m_frames.size() || !m_frames[index].m_haveMetadata)
-        cacheFrame(index);
-
     return m_frames[index].m_duration;
 }
 
@@ -308,12 +319,8 @@ NativeImagePtr BitmapImage::nativeImageForCurrentFrame()
 
 bool BitmapImage::frameHasAlphaAtIndex(size_t index)
 {
-    if (index >= frameCount())
-        return true;
-
-    if (index >= m_frames.size() || !m_frames[index].m_haveMetadata)
-        cacheFrame(index);
-
+    if (!ensureFrameIsCached(index))
+        return true; // Why does an invalid index mean alpha?
     return m_frames[index].m_hasAlpha;
 }
 
@@ -322,6 +329,18 @@ bool BitmapImage::currentFrameHasAlpha()
     return frameHasAlphaAtIndex(currentFrame());
 }
 
+ImageOrientation BitmapImage::currentFrameOrientation()
+{
+    return frameOrientationAtIndex(currentFrame());
+}
+
+ImageOrientation BitmapImage::frameOrientationAtIndex(size_t index)
+{
+    if (!ensureFrameIsCached(index))
+        return DefaultImageOrientation;
+    return m_frames[index].m_orientation;
+}
+
 #if !ASSERT_DISABLED
 bool BitmapImage::notSolidColor()
 {
@@ -539,4 +558,11 @@ Color BitmapImage::solidColor() const
     return m_solidColor;
 }
 
+#if !USE(CG)
+void BitmapImage::draw(GraphicsContext* ctx, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator op, RespectImageOrientationEnum)
+{
+    draw(ctx, dstRect, srcRect, styleColorSpace, op);
+}
+#endif
+
 }
index 44d8baf..7af6ff8 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "Image.h"
 #include "Color.h"
+#include "ImageOrientation.h"
 #include "IntSize.h"
 
 #if PLATFORM(MAC)
@@ -69,6 +70,7 @@ struct FrameData {
 public:
     FrameData()
         : m_frame(0)
+        , m_orientation(DefaultImageOrientation)
         , m_duration(0)
         , m_haveMetadata(false)
         , m_isComplete(false)
@@ -86,6 +88,7 @@ public:
     bool clear(bool clearMetadata);
 
     NativeImagePtr m_frame;
+    ImageOrientation m_orientation;
     float m_duration;
     bool m_haveMetadata : 1;
     bool m_isComplete : 1;
@@ -117,6 +120,7 @@ public:
     virtual bool hasSingleSecurityOrigin() const;
 
     virtual IntSize size() const;
+    IntSize sizeRespectingOrientation() const;
     IntSize currentFrameSize() const;
     virtual bool getHotSpot(IntPoint&) const;
 
@@ -128,7 +132,7 @@ public:
     // automatically pause once all observers no longer want to render the image anywhere.
     virtual void stopAnimation();
     virtual void resetAnimation();
-    
+
     virtual unsigned decodedSize() const;
 
 #if PLATFORM(MAC)
@@ -165,6 +169,9 @@ public:
     bool frameHasAlphaAtIndex(size_t);
     virtual bool currentFrameHasAlpha();
 
+    ImageOrientation currentFrameOrientation();
+    ImageOrientation frameOrientationAtIndex(size_t);
+
 #if !ASSERT_DISABLED
     virtual bool notSolidColor();
 #endif
@@ -186,6 +193,7 @@ protected:
     virtual void drawFrameMatchingSourceSize(GraphicsContext*, const FloatRect& dstRect, const IntSize& srcSize, ColorSpace styleColorSpace, CompositeOperator);
 #endif
     virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator);
+    void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator, RespectImageOrientationEnum);
 
 #if (OS(WINCE) && !PLATFORM(QT))
     virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform,
@@ -200,6 +208,8 @@ protected:
 
     // Decodes and caches a frame. Never accessed except internally.
     void cacheFrame(size_t index);
+    // Called before accessing m_frames[index]. Returns false on index out of bounds.
+    bool ensureFrameIsCached(size_t index);
 
     // Called to invalidate cached data.  When |destroyAll| is true, we wipe out
     // the entire frame buffer cache and tell the image source to destroy
@@ -254,6 +264,7 @@ protected:
     
     ImageSource m_source;
     mutable IntSize m_size; // The size to use for the overall image (will just be the size of the first image).
+    mutable IntSize m_sizeRespectingOrientation;
     
     size_t m_currentFrame; // The index of the current frame of animation.
     Vector<FrameData> m_frames; // An array of the cached frames of the animation. We have to ref frames to pin them in the cache.
index e688938..26b1bb7 100644 (file)
@@ -27,6 +27,7 @@
 #include "GraphicsContext.h"
 
 #include "BidiResolver.h"
+#include "BitmapImage.h"
 #include "Font.h"
 #include "Generator.h"
 #include "ImageBuffer.h"
@@ -437,27 +438,27 @@ void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run,
     fillRect(font.selectionRectForText(run, point, h, from, to), backgroundColor, colorSpace);
 }
 
-void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const IntPoint& p, CompositeOperator op)
+void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const IntPoint& p, CompositeOperator op, RespectImageOrientationEnum shouldRespectImageOrientation)
 {
-    drawImage(image, styleColorSpace, p, IntRect(0, 0, -1, -1), op);
+    drawImage(image, styleColorSpace, p, IntRect(0, 0, -1, -1), op, shouldRespectImageOrientation);
 }
 
-void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const IntRect& r, CompositeOperator op, bool useLowQualityScale)
+void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const IntRect& r, CompositeOperator op, RespectImageOrientationEnum shouldRespectImageOrientation, bool useLowQualityScale)
 {
-    drawImage(image, styleColorSpace, r, IntRect(0, 0, -1, -1), op, useLowQualityScale);
+    drawImage(image, styleColorSpace, r, IntRect(0, 0, -1, -1), op, shouldRespectImageOrientation, useLowQualityScale);
 }
 
-void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const IntPoint& dest, const IntRect& srcRect, CompositeOperator op)
+void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const IntPoint& dest, const IntRect& srcRect, CompositeOperator op, RespectImageOrientationEnum shouldRespectImageOrientation)
 {
-    drawImage(image, styleColorSpace, IntRect(dest, srcRect.size()), srcRect, op);
+    drawImage(image, styleColorSpace, IntRect(dest, srcRect.size()), srcRect, op, shouldRespectImageOrientation);
 }
 
-void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const IntRect& dest, const IntRect& srcRect, CompositeOperator op, bool useLowQualityScale)
+void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const IntRect& dest, const IntRect& srcRect, CompositeOperator op, RespectImageOrientationEnum shouldRespectImageOrientation, bool useLowQualityScale)
 {
-    drawImage(image, styleColorSpace, FloatRect(dest), srcRect, op, useLowQualityScale);
+    drawImage(image, styleColorSpace, FloatRect(dest), srcRect, op, shouldRespectImageOrientation, useLowQualityScale);
 }
 
-void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const FloatRect& dest, const FloatRect& src, CompositeOperator op, bool useLowQualityScale)
+void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const FloatRect& dest, const FloatRect& src, CompositeOperator op, RespectImageOrientationEnum shouldRespectImageOrientation, bool useLowQualityScale)
 {
     if (paintingDisabled() || !image)
         return;
@@ -477,14 +478,21 @@ void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const
     if (th == -1)
         th = image->height();
 
+    InterpolationQuality previousInterpolationQuality = InterpolationDefault;
+
     if (useLowQualityScale) {
-        InterpolationQuality previousInterpolationQuality = imageInterpolationQuality();
-        // FIXME: Should be InterpolationLow
+        previousInterpolationQuality = imageInterpolationQuality();
+        // FIXME (49002): Should be InterpolationLow
         setImageInterpolationQuality(InterpolationNone);
+    }
+
+    if (image->isBitmapImage())
+        static_cast<BitmapImage*>(image)->draw(this, FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(), FloatSize(tsw, tsh)), styleColorSpace, op, shouldRespectImageOrientation);
+    else
         image->draw(this, FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(), FloatSize(tsw, tsh)), styleColorSpace, op);
+
+    if (useLowQualityScale)
         setImageInterpolationQuality(previousInterpolationQuality);
-    } else
-        image->draw(this, FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(), FloatSize(tsw, tsh)), styleColorSpace, op);
 }
 
 void GraphicsContext::drawTiledImage(Image* image, ColorSpace styleColorSpace, const IntRect& destRect, const IntPoint& srcPoint, const IntSize& tileSize, CompositeOperator op, bool useLowQualityScale)
@@ -564,7 +572,7 @@ void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorS
 
     if (useLowQualityScale) {
         InterpolationQuality previousInterpolationQuality = imageInterpolationQuality();
-        // FIXME: Should be InterpolationLow
+        // FIXME (49002): Should be InterpolationLow
         setImageInterpolationQuality(InterpolationNone);
         image->draw(this, styleColorSpace, FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(), FloatSize(tsw, tsh)), op, useLowQualityScale);
         setImageInterpolationQuality(previousInterpolationQuality);
index 54095bd..1c81891 100644 (file)
@@ -32,6 +32,7 @@
 #include "FloatRect.h"
 #include "Gradient.h"
 #include "Image.h"
+#include "ImageOrientation.h"
 #include "Path.h"
 #include "Pattern.h"
 #include <wtf/Noncopyable.h>
@@ -260,8 +261,8 @@ namespace WebCore {
         void applyStrokePattern();
         void applyFillPattern();
         void drawPath(const Path&);
-        
-        void drawNativeImage(NativeImagePtr, const FloatSize& selfSize, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator = CompositeSourceOver);
+
+        void drawNativeImage(NativeImagePtr, const FloatSize& selfSize, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator = CompositeSourceOver, ImageOrientation = DefaultImageOrientation);
 
         // Allow font smoothing (LCD antialiasing). Not part of the graphics state.
         void setAllowsFontSmoothing(bool);
@@ -306,12 +307,12 @@ namespace WebCore {
 
         void strokeRect(const FloatRect&, float lineWidth);
 
-        void drawImage(Image*, ColorSpace styleColorSpace, const IntPoint&, CompositeOperator = CompositeSourceOver);
-        void drawImage(Image*, ColorSpace styleColorSpace, const IntRect&, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
-        void drawImage(Image*, ColorSpace styleColorSpace, const IntPoint& destPoint, const IntRect& srcRect, CompositeOperator = CompositeSourceOver);
-        void drawImage(Image*, ColorSpace styleColorSpace, const IntRect& destRect, const IntRect& srcRect, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
+        void drawImage(Image*, ColorSpace styleColorSpace, const IntPoint&, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
+        void drawImage(Image*, ColorSpace styleColorSpace, const IntRect&, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation, bool useLowQualityScale = false);
+        void drawImage(Image*, ColorSpace styleColorSpace, const IntPoint& destPoint, const IntRect& srcRect, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
+        void drawImage(Image*, ColorSpace styleColorSpace, const IntRect& destRect, const IntRect& srcRect, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation, bool useLowQualityScale = false);
         void drawImage(Image*, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1),
-                       CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
+                       CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation, bool useLowQualityScale = false);
         void drawTiledImage(Image*, ColorSpace styleColorSpace, const IntRect& destRect, const IntPoint& srcPoint, const IntSize& tileSize,
                        CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
         void drawTiledImage(Image*, ColorSpace styleColorSpace, const IntRect& destRect, const IntRect& srcRect,
diff --git a/Source/WebCore/platform/graphics/ImageOrientation.cpp b/Source/WebCore/platform/graphics/ImageOrientation.cpp
new file mode 100644 (file)
index 0000000..8a5854e
--- /dev/null
@@ -0,0 +1,60 @@
+
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ImageOrientation.h"
+
+#include "AffineTransform.h"
+
+namespace WebCore {
+
+AffineTransform ImageOrientation::transformFromDefault(const FloatSize& drawnSize) const
+{
+    float w = drawnSize.width();
+    float h = drawnSize.height();
+    switch (m_orientation) {
+    case OriginTopLeft:
+        return AffineTransform();
+    case OriginBottomRight:
+        return AffineTransform(-1,  0,  0, -1,  w, h);
+    case OriginLeftBottom:
+        return AffineTransform( 0,  1, -1,  0,  w, 0);
+    case OriginRightTop:
+        return AffineTransform( 0, -1,  1,  0,  0, h);
+    case OriginTopRight:
+        return AffineTransform(-1,  0,  0,  1,  w, 0);
+    case OriginBottomLeft:
+        return AffineTransform( 1,  0,  0, -1,  0, h);
+    case OriginLeftTop:
+        return AffineTransform( 0, -1, -1,  0,  w, h);
+    case OriginRightBottom:
+        return AffineTransform( 0,  1,  1,  0,  0, 0);
+    }
+    ASSERT_NOT_REACHED();
+    return AffineTransform();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/ImageOrientation.h b/Source/WebCore/platform/graphics/ImageOrientation.h
new file mode 100644 (file)
index 0000000..86be5fe
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ImageOrientation_h
+#define ImageOrientation_h
+
+namespace WebCore {
+
+class AffineTransform;
+class FloatSize;
+
+// This enum intentionally matches the orientation values from the EXIF spec.
+// See JEITA CP-3451, page 18. http://www.exif.org/Exif2-2.PDF
+enum ImageOrientationEnum {
+    // "TopLeft" means that the 0 row starts at the Top, the 0 column starts at the Left.
+    OriginTopLeft = 1, // default
+    OriginTopRight = 2, // mirror along y-axes
+    OriginBottomRight = 3, // 180 degree rotation
+    OriginBottomLeft = 4, // mirror along the x-axes
+    OriginLeftTop = 5, // -90 degree rotation + mirror along x-axes
+    OriginRightTop = 6, // 90 degree rotation
+    OriginRightBottom = 7, // 90 degree rotation + mirror along x-axes
+    OriginLeftBottom = 8, // -90 degree rotation
+    // All other values are "reserved" as of EXIF 2.2
+    DefaultImageOrientation = OriginTopLeft,
+};
+
+enum RespectImageOrientationEnum {
+    DoNotRespectImageOrientation = 0,
+    RespectImageOrientation = 1
+};
+
+class ImageOrientation {
+public:
+    ImageOrientation(ImageOrientationEnum orientation = DefaultImageOrientation)
+        : m_orientation(orientation)
+    {
+    }
+
+    bool usesWidthAsHeight() const
+    {
+        // Values 5 through 8 all flip the width/height.
+        return m_orientation >= OriginLeftTop;
+    }
+
+    // ImageOrientationEnum currently matches EXIF values, however code outside
+    // this function should never assume that.
+    static ImageOrientation fromEXIFValue(int exifValue)
+    {
+        // Values direct from images may be invalid, in which case we use the default.
+        if (exifValue < OriginTopLeft || exifValue > OriginLeftBottom)
+            return DefaultImageOrientation;
+        return static_cast<ImageOrientationEnum>(exifValue);
+    }
+
+    // This transform can be used for drawing an image according to the orientation.
+    AffineTransform transformFromDefault(const FloatSize& drawnSize) const;
+
+    inline bool operator==(const ImageOrientation& other) const { return other.m_orientation == m_orientation; }
+    inline bool operator!=(const ImageOrientation& other) const { return !(*this == other); }
+
+private:
+    // FIXME: This only needs to be one byte.
+    ImageOrientationEnum m_orientation;
+};
+
+} // namespace WebCore
+
+#endif // ImageOrientation_h
index f4495ed..ff9fe0d 100644 (file)
@@ -35,6 +35,9 @@
 #include "ImageDecoder.h"
 #endif
 
+#include "ImageOrientation.h"
+#include "NotImplemented.h"
+
 namespace WebCore {
 
 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
@@ -100,13 +103,21 @@ bool ImageSource::isSizeAvailable()
     return m_decoder && m_decoder->isSizeAvailable();
 }
 
-IntSize ImageSource::size() const
+IntSize ImageSource::size(RespectImageOrientationEnum shouldRespectOrientation) const
 {
+    // The JPEG and TIFF decoders need to be taught how to read EXIF, XMP, or IPTC data.
+    if (shouldRespectOrientation == RespectImageOrientation)
+        notImplemented();
+
     return m_decoder ? m_decoder->size() : IntSize();
 }
 
-IntSize ImageSource::frameSizeAtIndex(size_t index) const
+IntSize ImageSource::frameSizeAtIndex(size_t index, RespectImageOrientationEnum shouldRespectOrientation) const
 {
+    // The JPEG and TIFF decoders need to be taught how to read EXIF, XMP, or IPTC data.
+    if (shouldRespectOrientation == RespectImageOrientation)
+        notImplemented();
+
     return m_decoder ? m_decoder->frameSizeAtIndex(index) : IntSize();
 }
 
@@ -168,6 +179,13 @@ float ImageSource::frameDurationAtIndex(size_t index)
     return duration;
 }
 
+ImageOrientation ImageSource::orientationAtIndex(size_t index) const
+{
+    // The JPEG and TIFF decoders need to be taught how to read EXIF, XMP, or IPTC data.
+    notImplemented();
+    return DefaultImageOrientation;
+}
+
 bool ImageSource::frameHasAlphaAtIndex(size_t index)
 {
     // When a frame has not finished decoding, always mark it as having alpha.
index 1d02202..3a7fafc 100644 (file)
@@ -27,6 +27,8 @@
 #ifndef ImageSource_h
 #define ImageSource_h
 
+#include "ImageOrientation.h"
+
 #include <wtf/Forward.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/Vector.h>
@@ -56,6 +58,7 @@ class NativeImageSkia;
 
 namespace WebCore {
 
+class ImageOrientation;
 class IntPoint;
 class IntSize;
 class SharedBuffer;
@@ -172,8 +175,9 @@ public:
     String filenameExtension() const;
 
     bool isSizeAvailable();
-    IntSize size() const;
-    IntSize frameSizeAtIndex(size_t) const;
+    IntSize size(RespectImageOrientationEnum = DoNotRespectImageOrientation) const;
+    IntSize frameSizeAtIndex(size_t, RespectImageOrientationEnum = DoNotRespectImageOrientation) const;
+
     bool getHotSpot(IntPoint&) const;
 
     size_t bytesDecodedToDetermineProperties() const;
@@ -189,6 +193,7 @@ public:
     float frameDurationAtIndex(size_t);
     bool frameHasAlphaAtIndex(size_t); // Whether or not the frame actually used any alpha.
     bool frameIsCompleteAtIndex(size_t); // Whether or not the frame is completely decoded.
+    ImageOrientation orientationAtIndex(size_t) const; // EXIF image orientation
 
 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
     static unsigned maxPixelsPerDecodedImage() { return s_maxPixelsPerDecodedImage; }
index 346f851..73f0bdf 100644 (file)
@@ -196,7 +196,7 @@ void GraphicsContext3D::paintToCanvas(const unsigned char* imagePixels, int imag
     FloatRect dst(0, 0, imageWidth, imageHeight);
 
     RefPtr<BitmapImageSingleFrameSkia> bitmapImage = BitmapImageSingleFrameSkia::create(canvasBitmap, false);
-    context->drawImage(bitmapImage.get(), ColorSpaceDeviceRGB, dst, src, CompositeCopy, false);
+    context->drawImage(bitmapImage.get(), ColorSpaceDeviceRGB, dst, src, CompositeCopy, DoNotRespectImageOrientation, false);
 }
 
 void GraphicsContext3D::setContextLostCallback(PassOwnPtr<ContextLostCallback>)
index 26b2515..8bb01b5 100644 (file)
@@ -99,7 +99,7 @@ void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, con
 {
     // BitmapImage will release the passed in surface on destruction
     RefPtr<Image> image = BitmapImage::create(cairo_surface_reference(m_data.m_surface));
-    context->drawImage(image.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
+    context->drawImage(image.get(), styleColorSpace, destRect, srcRect, op, DoNotRespectImageOrientation, useLowQualityScale);
 }
 
 void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform,
index 8b404f3..6310eb5 100644 (file)
@@ -32,6 +32,7 @@
 #include "FloatConversion.h"
 #include "GraphicsContextPlatformPrivateCG.h"
 #include "ImageBuffer.h"
+#include "ImageOrientation.h"
 #include "KURL.h"
 #include "Path.h"
 #include "Pattern.h"
@@ -170,11 +171,12 @@ void GraphicsContext::restorePlatformState()
     m_data->m_userToDeviceTransformKnownToBeIdentity = false;
 }
 
-void GraphicsContext::drawNativeImage(NativeImagePtr imagePtr, const FloatSize& imageSize, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op)
+void GraphicsContext::drawNativeImage(NativeImagePtr imagePtr, const FloatSize& imageSize, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, ImageOrientation orientation)
 {
     RetainPtr<CGImageRef> image(imagePtr);
 
-    float currHeight = CGImageGetHeight(image.get());
+    float currHeight = orientation.usesWidthAsHeight() ? CGImageGetWidth(image.get()) : CGImageGetHeight(image.get());
+
     if (currHeight <= srcRect.y())
         return;
 
@@ -231,8 +233,18 @@ void GraphicsContext::drawNativeImage(NativeImagePtr imagePtr, const FloatSize&
     setPlatformCompositeOperation(op);
 
     // Flip the coords.
+    CGContextTranslateCTM(context, adjustedDestRect.x(), adjustedDestRect.maxY());
     CGContextScaleCTM(context, 1, -1);
-    adjustedDestRect.setY(-adjustedDestRect.maxY());
+    adjustedDestRect.setLocation(FloatPoint());
+
+    if (orientation != DefaultImageOrientation) {
+        CGContextConcatCTM(context, orientation.transformFromDefault(adjustedDestRect.size()));
+        if (orientation.usesWidthAsHeight()) {
+            // The destination rect will have it's width and height already reversed for the orientation of
+            // the image, as it was needed for page layout, so we need to reverse it back here.
+            adjustedDestRect = FloatRect(adjustedDestRect.x(), adjustedDestRect.y(), adjustedDestRect.height(), adjustedDestRect.width());
+        }
+    }
     
     // Adjust the color space.
     image = Image::imageWithColorSpace(image.get(), styleColorSpace);
index d81c780..559ba1f 100644 (file)
@@ -54,6 +54,8 @@ bool FrameData::clear(bool clearMetadata)
     if (clearMetadata)
         m_haveMetadata = false;
 
+    m_orientation = DefaultImageOrientation;
+
     if (m_frame) {
         CGImageRelease(m_frame);
         m_frame = 0;
@@ -95,6 +97,7 @@ BitmapImage::BitmapImage(CGImageRef cgImage, ImageObserver* observer)
     m_frames[0].m_frame = cgImage;
     m_frames[0].m_hasAlpha = true;
     m_frames[0].m_haveMetadata = true;
+
     checkForSolidColor();
 }
 
@@ -182,7 +185,12 @@ RetainPtr<CFArrayRef> BitmapImage::getCGImageArray()
     return RetainPtr<CFArrayRef>(AdoptCF, array);
 }
 
-void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp)
+void BitmapImage::draw(GraphicsContext* ctx, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator op)
+{
+    draw(ctx, dstRect, srcRect, styleColorSpace, op, DoNotRespectImageOrientation);
+}
+
+void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp, RespectImageOrientationEnum shouldRespectImageOrientation)
 {
     startAnimation();
 
@@ -196,8 +204,12 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const F
     }
 
     FloatSize selfSize = currentFrameSize();
+    ImageOrientation orientation = DefaultImageOrientation;
+
+    if (shouldRespectImageOrientation == RespectImageOrientation)
+        orientation = frameOrientationAtIndex(m_currentFrame);
 
-    ctxt->drawNativeImage(image.get(), selfSize, styleColorSpace, destRect, srcRect, compositeOp);
+    ctxt->drawNativeImage(image.get(), selfSize, styleColorSpace, destRect, srcRect, compositeOp, orientation);
 
     if (imageObserver())
         imageObserver()->didDraw(this);
index 35b5bfe..939427c 100644 (file)
@@ -29,6 +29,7 @@
 #if USE(CG)
 #include "ImageSourceCG.h"
 
+#include "ImageOrientation.h"
 #include "IntPoint.h"
 #include "IntSize.h"
 #include "MIMETypeRegistry.h"
@@ -114,7 +115,17 @@ static CFDictionaryRef imageSourceOptions(ImageSource::ShouldSkipMetaData skipMe
 
     if (!options) {
         const unsigned numOptions = 3;
+
+#if defined(BUILDING_ON_LION) || defined(BUILDING_ON_SNOW_LEOPARD)
+        // Lion and Snow Leopard only return Orientation when kCGImageSourceSkipMetaData is false,
+        // and incorrectly return cached metadata if an image is queried once with kCGImageSourceSkipMetaData true
+        // and then subsequently with kCGImageSourceSkipMetaData false.
+        // <rdar://problem/11148192>
+        UNUSED_PARAM(skipMetaData);
+        const CFBooleanRef imageSourceSkipMetaData = kCFBooleanFalse;
+#else
         const CFBooleanRef imageSourceSkipMetaData = (skipMetaData == ImageSource::SkipMetaData) ? kCFBooleanTrue : kCFBooleanFalse;
+#endif
         const void* keys[numOptions] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32, kCGImageSourceSkipMetaData };
         const void* values[numOptions] = { kCFBooleanTrue, kCFBooleanTrue, imageSourceSkipMetaData };
         options = CFDictionaryCreate(NULL, keys, values, numOptions, 
@@ -185,26 +196,45 @@ bool ImageSource::isSizeAvailable()
     return result;
 }
 
-IntSize ImageSource::frameSizeAtIndex(size_t index) const
+IntSize ImageSource::frameSizeAtIndex(size_t index, RespectImageOrientationEnum shouldRespectOrientation) const
 {
-    IntSize result;
     RetainPtr<CFDictionaryRef> properties(AdoptCF, CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions(SkipMetaData)));
-    if (properties) {
-        int w = 0, h = 0;
-        CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelWidth);
-        if (num)
-            CFNumberGetValue(num, kCFNumberIntType, &w);
-        num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelHeight);
-        if (num)
-            CFNumberGetValue(num, kCFNumberIntType, &h);
-        result = IntSize(w, h);
-    }
-    return result;
+
+    if (!properties)
+        return IntSize();
+
+    int w = 0, h = 0;
+    CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelWidth);
+    if (num)
+        CFNumberGetValue(num, kCFNumberIntType, &w);
+    num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelHeight);
+    if (num)
+        CFNumberGetValue(num, kCFNumberIntType, &h);
+
+    if ((shouldRespectOrientation == RespectImageOrientation) && orientationAtIndex(index).usesWidthAsHeight())
+        return IntSize(h, w);
+
+    return IntSize(w, h);
+}
+
+ImageOrientation ImageSource::orientationAtIndex(size_t index) const
+{
+    RetainPtr<CFDictionaryRef> properties(AdoptCF, CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions(SkipMetaData)));
+    if (!properties)
+        return DefaultImageOrientation;
+
+    CFNumberRef orientationProperty = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyOrientation);
+    if (!orientationProperty)
+        return DefaultImageOrientation;
+
+    int exifValue;
+    CFNumberGetValue(orientationProperty, kCFNumberIntType, &exifValue);
+    return ImageOrientation::fromEXIFValue(exifValue);
 }
 
-IntSize ImageSource::size() const
+IntSize ImageSource::size(RespectImageOrientationEnum shouldRespectOrientation) const
 {
-    return frameSizeAtIndex(0);
+    return frameSizeAtIndex(0, shouldRespectOrientation);
 }
 
 bool ImageSource::getHotSpot(IntPoint& hotSpot) const
index 6ee7a79..6a643c8 100644 (file)
@@ -35,6 +35,7 @@
 #include "GraphicsContext.h"
 #include "GraphicsTypes.h"
 #include "ImageGStreamer.h"
+#include "ImageOrientation.h"
 #include "IntRect.h"
 #include "KURL.h"
 #include "MIMETypeRegistry.h"
@@ -1497,7 +1498,7 @@ void MediaPlayerPrivateGStreamer::paint(GraphicsContext* context, const IntRect&
         return;
 
     context->drawImage(reinterpret_cast<Image*>(gstImage->image().get()), ColorSpaceSRGB,
-                       rect, CompositeCopy, false);
+                       rect, CompositeCopy, DoNotRespectImageOrientation, false);
 }
 
 static HashSet<String> mimeTypeCache()
index f9e4713..5ef15f6 100644 (file)
@@ -131,9 +131,9 @@ void ImageBuffer::draw(GraphicsContext* destContext, ColorSpace styleColorSpace,
     if (destContext == context()) {
         // We're drawing into our own buffer.  In order for this to work, we need to copy the source buffer first.
         RefPtr<Image> copy = copyImage(CopyBackingStore);
-        destContext->drawImage(copy.get(), ColorSpaceDeviceRGB, destRect, srcRect, op, useLowQualityScale);
+        destContext->drawImage(copy.get(), ColorSpaceDeviceRGB, destRect, srcRect, op, DoNotRespectImageOrientation, useLowQualityScale);
     } else
-        destContext->drawImage(m_data.m_image.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
+        destContext->drawImage(m_data.m_image.get(), styleColorSpace, destRect, srcRect, op, DoNotRespectImageOrientation, useLowQualityScale);
 }
 
 void ImageBuffer::drawPattern(GraphicsContext* destContext, const FloatRect& srcRect, const AffineTransform& patternTransform,
index 0516446..5e7258d 100644 (file)
@@ -195,7 +195,7 @@ void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, con
                        CompositeOperator op, bool useLowQualityScale)
 {
     RefPtr<Image> image = BitmapImageSingleFrameSkia::create(*m_data.m_platformContext.bitmap(), drawNeedsCopy(m_context.get(), context));
-    context->drawImage(image.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
+    context->drawImage(image.get(), styleColorSpace, destRect, srcRect, op, DoNotRespectImageOrientation, useLowQualityScale);
 }
 
 void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform,
index a626e7b..909591b 100644 (file)
@@ -110,7 +110,7 @@ void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, con
                        CompositeOperator op , bool useLowQualityScale)
 {
     RefPtr<Image> imageCopy = copyImage(CopyBackingStore);
-    context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
+    context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, DoNotRespectImageOrientation, useLowQualityScale);
 }
 
 void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform,
index 646cc66..b3a7869 100644 (file)
@@ -161,7 +161,7 @@ void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const
 void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, bool useLowQualityScale)
 {
     RefPtr<Image> imageCopy = copyImage(CopyBackingStore);
-    context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
+    context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, DoNotRespectImageOrientation, useLowQualityScale);
 }
 
 void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform,
index 71a65e1..6ac387f 100644 (file)
@@ -73,7 +73,7 @@ DragImageRef dissolveDragImageToFraction(DragImageRef image, float fraction)
     return image;
 }
 
-DragImageRef createDragImageFromImage(Image* image)
+DragImageRef createDragImageFromImage(Image* image, RespectImageOrientationEnum)
 {
     return cairo_surface_reference(image->nativeImageForCurrentFrame());
 }
index d57648f..3379f39 100644 (file)
@@ -27,6 +27,7 @@
 #import "DragImage.h"
 
 #if ENABLE(DRAG_SUPPORT)
+#import "BitmapImage.h"
 #import "CachedImage.h"
 #import "Font.h"
 #import "FontCache.h"
@@ -84,10 +85,40 @@ RetainPtr<NSImage> dissolveDragImageToFraction(RetainPtr<NSImage> image, float d
     return image;
 }
         
-RetainPtr<NSImage> createDragImageFromImage(Image* image)
+RetainPtr<NSImage> createDragImageFromImage(Image* image, RespectImageOrientationEnum shouldRespectImageOrientation)
 {
+    IntSize size = image->size();
+
+    if (image->isBitmapImage()) {
+        ImageOrientation orientation = DefaultImageOrientation;
+        BitmapImage* bitmapImage = static_cast<BitmapImage *>(image);
+        IntSize sizeRespectingOrientation = bitmapImage->sizeRespectingOrientation();
+
+        if (shouldRespectImageOrientation == RespectImageOrientation)
+            orientation = bitmapImage->currentFrameOrientation();
+
+        if (orientation != DefaultImageOrientation) {
+            // Construct a correctly-rotated copy of the image to use as the drag image.
+            RetainPtr<NSAffineTransform> cocoaTransform(AdoptNS, [[NSAffineTransform alloc] init]);
+            CGAffineTransform transform = orientation.transformFromDefault(sizeRespectingOrientation);
+            [cocoaTransform.get() setTransformStruct:*(NSAffineTransformStruct*)&transform];
+
+            FloatRect destRect(FloatPoint(), sizeRespectingOrientation);
+
+            RetainPtr<NSImage> rotatedDragImage(AdoptNS, [[NSImage alloc] initWithSize:(NSSize)(sizeRespectingOrientation)]);
+            [rotatedDragImage.get() lockFocus];
+            [cocoaTransform.get() concat];
+            if (orientation.usesWidthAsHeight())
+                destRect = FloatRect(destRect.x(), destRect.y(), destRect.height(), destRect.width());
+            [image->getNSImage() drawInRect:destRect fromRect:NSMakeRect(0, 0, size.width(), size.height()) operation:NSCompositeSourceOver fraction:1.0];
+            [rotatedDragImage.get() unlockFocus];
+
+            return rotatedDragImage;
+        }
+    }
+
     RetainPtr<NSImage> dragImage(AdoptNS, [image->getNSImage() copy]);
-    [dragImage.get() setSize:(NSSize)(image->size())];
+    [dragImage.get() setSize:(NSSize)size];
     return dragImage;
 }
     
index 42ad6e9..0e7ce04 100644 (file)
@@ -61,7 +61,7 @@ DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
     return image;
 }
 
-DragImageRef createDragImageFromImage(Image* image)
+DragImageRef createDragImageFromImage(Image* image, RespectImageOrientationEnum)
 {
     if (!image || !image->nativeImageForCurrentFrame())
         return 0;
index 9c445c1..cb49f95 100644 (file)
@@ -120,7 +120,7 @@ exit:
     return hbmp;
 }
     
-DragImageRef createDragImageFromImage(Image* img)
+DragImageRef createDragImageFromImage(Image* img, RespectImageOrientationEnum)
 {
     HBITMAP hbmp = 0;
     HWndDC dc(0);
index 69208b5..f65211f 100644 (file)
@@ -150,7 +150,7 @@ exit:
     return hbmp;
 }
     
-DragImageRef createDragImageFromImage(Image* img)
+DragImageRef createDragImageFromImage(Image* img, RespectImageOrientationEnum)
 {
     HBITMAP hbmp = 0;
     HDC dc = GetDC(0);
index f639b41..14df480 100644 (file)
@@ -50,7 +50,7 @@ DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
     return image;
 }
 
-DragImageRef createDragImageFromImage(Image*)
+DragImageRef createDragImageFromImage(Image*, RespectImageOrientationEnum)
 {
     return 0;
 }
index df2dcee..3883330 100644 (file)
@@ -50,7 +50,7 @@ DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
     return image;
 }
         
-DragImageRef createDragImageFromImage(Image*)
+DragImageRef createDragImageFromImage(Image*, RespectImageOrientationEnum)
 {
     return 0;
 }
index 0c79fcd..9b37578 100644 (file)
@@ -307,7 +307,7 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOf
                 if (centerY < 0)
                     centerY = 0;
                 imageOffset = LayoutSize(leftBorder + leftPad + centerX + 1, topBorder + topPad + centerY + 1);
-                context->drawImage(image.get(), style()->colorSpace(), IntRect(roundedIntPoint(paintOffset + imageOffset), imageSize));
+                context->drawImage(image.get(), style()->colorSpace(), IntRect(roundedIntPoint(paintOffset + imageOffset), imageSize), CompositeSourceOver, shouldRespectImageOrientation());
                 errorPictureDrawn = true;
             }
 
@@ -429,7 +429,7 @@ void RenderImage::paintIntoRect(GraphicsContext* context, const LayoutRect& rect
     CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver;
     Image* image = m_imageResource->image().get();
     bool useLowQualityScaling = shouldPaintAtLowQuality(context, image, image, alignedRect.size());
-    context->drawImage(m_imageResource->image(alignedRect.width(), alignedRect.height()).get(), style()->colorSpace(), alignedRect, compositeOperator, useLowQualityScaling);
+    context->drawImage(m_imageResource->image(alignedRect.width(), alignedRect.height()).get(), style()->colorSpace(), alignedRect, compositeOperator, shouldRespectImageOrientation(), useLowQualityScaling);
 }
 
 bool RenderImage::backgroundIsObscured() const
index 4b49625..96d25d6 100755 (executable)
@@ -2200,6 +2200,13 @@ RenderObject* RenderObject::rendererForRootBackground()
     return this;
 }
 
+RespectImageOrientationEnum RenderObject::shouldRespectImageOrientation() const
+{
+    // Respect the image's orientation if it's being used as a full-page image or it's
+    // an <img> and the setting to respect it everywhere is set.
+    return document()->isImageDocument() || (document()->settings() && document()->settings()->shouldRespectImageOrientation() && node() && node()->hasTagName(HTMLNames::imgTag)) ? RespectImageOrientation : DoNotRespectImageOrientation;
+}
+
 bool RenderObject::hasOutlineAnnotation() const
 {
     return node() && node()->isLink() && document()->printing();
index ac70d13..e731095 100644 (file)
@@ -856,6 +856,8 @@ public:
     // Return the renderer whose background style is used to paint the root background. Should only be called on the renderer for which isRoot() is true.
     RenderObject* rendererForRootBackground();
 
+    RespectImageOrientationEnum shouldRespectImageOrientation() const;
+
 protected:
     inline bool layerCreationAllowedForSubtree() const;
 
index dd407be..748362c 100644 (file)
@@ -1,3 +1,24 @@
+2012-04-06  Tim Horton  <timothy_horton@apple.com>
+
+        Add autodetection of image orientation from EXIF information
+        https://bugs.webkit.org/show_bug.cgi?id=19688
+        <rdar://problem/4126979> and <rdar://problem/11091578>
+
+        Original patch by David Carson and Eric Seidel.
+
+        Reviewed by Simon Fraser.
+
+        Add a preference, ShouldRespectImageOrientation, which will cause WebCore to respect EXIF orientation in all images.
+
+        * WebView/WebPreferenceKeysPrivate.h:
+        * WebView/WebPreferences.mm:
+        (+[WebPreferences initialize]):
+        (-[WebPreferences setShouldRespectImageOrientation:]):
+        (-[WebPreferences shouldRespectImageOrientation]):
+        * WebView/WebPreferencesPrivate.h:
+        * WebView/WebView.mm:
+        (-[WebView _preferencesChanged:]):
+
 2012-04-06  Dan Bernstein  <mitz@apple.com>
 
         <rdar://problem/10912476> HiDPI: Have canvas use a hidpi backing store, but downsample upon access
index e7e8b07..c585f84 100644 (file)
 #define WebKitNotificationsEnabledKey @"WebKitNotificationsEnabled"
 #define WebKitSuppressesIncrementalRenderingKey @"WebKitSuppressesIncrementalRendering"
 #define WebKitRegionBasedColumnsEnabledKey @"WebKitRegionBasedColumnsEnabled"
+#define WebKitShouldRespectImageOrientationKey @"WebKitShouldRespectImageOrientation"
 
 // These are private both because callers should be using the cover methods and because the
 // cover methods themselves are private.
index 87eb150..a06a325 100644 (file)
@@ -396,6 +396,7 @@ static WebCacheModel cacheModelForMainBundle(void)
         [NSNumber numberWithBool:NO],   WebKitShouldDisplayCaptionsPreferenceKey,
         [NSNumber numberWithBool:NO],   WebKitShouldDisplayTextDescriptionsPreferenceKey,
         [NSNumber numberWithBool:YES],  WebKitNotificationsEnabledKey,
+        [NSNumber numberWithBool:NO],   WebKitShouldRespectImageOrientationKey,
 
         [NSNumber numberWithLongLong:ApplicationCacheStorage::noQuota()], WebKitApplicationCacheTotalQuota,
         [NSNumber numberWithLongLong:ApplicationCacheStorage::noQuota()], WebKitApplicationCacheDefaultOriginQuota,
@@ -1675,6 +1676,16 @@ static NSString *classIBCreatorID = nil;
     return [self _boolValueForKey:WebKitRegionBasedColumnsEnabledKey];
 }
 
+- (void)setShouldRespectImageOrientation:(BOOL)flag
+{
+    [self _setBoolValue:flag forKey:WebKitShouldRespectImageOrientationKey];
+}
+
+- (BOOL)shouldRespectImageOrientation
+{
+    return [self _boolValueForKey:WebKitShouldRespectImageOrientationKey];
+}
+
 @end
 
 @implementation WebPreferences (WebInternal)
index d751647..5579894 100644 (file)
@@ -296,4 +296,7 @@ extern NSString *WebPreferencesChangedInternalNotification;
 - (void)setNotificationsEnabled:(BOOL)flag;
 - (BOOL)notificationsEnabled;
 
+- (void)setShouldRespectImageOrientation:(BOOL)flag;
+- (BOOL)shouldRespectImageOrientation;
+
 @end
index a64accc..3ff8867 100644 (file)
@@ -1517,6 +1517,7 @@ static bool needsSelfRetainWhileLoadingQuirk()
     settings->setShouldDisplayTextDescriptions([preferences shouldDisplayTextDescriptions]);
 #endif
 
+    settings->setShouldRespectImageOrientation([preferences shouldRespectImageOrientation]);
     settings->setNeedsIsLoadingInAPISenseQuirk([self _needsIsLoadingInAPISenseQuirk]);
 
     // Application Cache Preferences are stored on the global cache storage manager, not in Settings.
index 50d8a15..b4b48c6 100644 (file)
@@ -1,3 +1,24 @@
+2012-04-06  Tim Horton  <timothy_horton@apple.com>
+
+        Add autodetection of image orientation from EXIF information
+        https://bugs.webkit.org/show_bug.cgi?id=19688
+        <rdar://problem/4126979> and <rdar://problem/11091578>
+
+        Original patch by David Carson and Eric Seidel.
+
+        Reviewed by Simon Fraser.
+
+        Add a preference, ShouldRespectImageOrientation, which will cause WebCore to respect EXIF orientation in all images.
+
+        * Shared/WebPreferencesStore.h:
+        (WebKit):
+        * UIProcess/API/C/WKPreferences.cpp:
+        (WKPreferencesSetShouldRespectImageOrientation):
+        (WKPreferencesGetShouldRespectImageOrientation):
+        * UIProcess/API/C/WKPreferences.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::updatePreferences):
+
 2012-04-06  Dan Bernstein  <mitz@apple.com>
 
         <rdar://problem/10912476> HiDPI: Have canvas use a hidpi backing store, but downsample upon access
index 8cc2b23..64f7b65 100644 (file)
@@ -109,6 +109,7 @@ namespace WebKit {
     macro(ShouldDisplayCaptions, shouldDisplayCaptions, Bool, bool, false) \
     macro(ShouldDisplayTextDescriptions, shouldDisplayTextDescriptions, Bool, bool, false) \
     macro(NotificationsEnabled, notificationsEnabled, Bool, bool, true) \
+    macro(ShouldRespectImageOrientation, shouldRespectImageOrientation, Bool, bool, false) \
     \
 
 #define FOR_EACH_WEBKIT_DOUBLE_PREFERENCE(macro) \
index 2c04045..5232337 100644 (file)
@@ -778,6 +778,16 @@ bool WKPreferencesGetNotificationsEnabled(WKPreferencesRef preferencesRef)
     return toImpl(preferencesRef)->notificationsEnabled();
 }
 
+void WKPreferencesSetShouldRespectImageOrientation(WKPreferencesRef preferencesRef, bool enabled)
+{
+    toImpl(preferencesRef)->setShouldRespectImageOrientation(enabled);
+}
+
+bool WKPreferencesGetShouldRespectImageOrientation(WKPreferencesRef preferencesRef)
+{
+    return toImpl(preferencesRef)->shouldRespectImageOrientation();
+}
+
 void WKPreferencesResetTestRunnerOverrides(WKPreferencesRef preferencesRef)
 {
     // Currently we reset the overrides on the web process when preferencesDidChange() is called. Since WTR preferences
index 8054e00..5e88573 100644 (file)
@@ -197,6 +197,10 @@ WK_EXPORT bool WKPreferencesGetShouldDisplayTextDescriptions(WKPreferencesRef pr
 WK_EXPORT void WKPreferencesSetNotificationsEnabled(WKPreferencesRef preferencesRef, bool enabled);
 WK_EXPORT bool WKPreferencesGetNotificationsEnabled(WKPreferencesRef preferencesRef);
 
+// Defaults to false
+WK_EXPORT void WKPreferencesSetShouldRespectImageOrientation(WKPreferencesRef preferencesRef, bool enabled);
+WK_EXPORT bool WKPreferencesGetShouldRespectImageOrientation(WKPreferencesRef preferencesRef);
+
 #ifdef __cplusplus
 }
 #endif
index a7e1ee6..74856ba 100644 (file)
@@ -1980,6 +1980,8 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
     settings->setNotificationsEnabled(store.getBoolValueForKey(WebPreferencesKey::notificationsEnabledKey()));
 #endif
 
+    settings->setShouldRespectImageOrientation(store.getBoolValueForKey(WebPreferencesKey::shouldRespectImageOrientationKey()));
+
     platformPreferencesDidChange(store);
 
     if (m_drawingArea)