[chromium] Drag image for image elements should be scaled with device scale factor.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 18 Jul 2012 18:43:13 +0000 (18:43 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 18 Jul 2012 18:43:13 +0000 (18:43 +0000)
https://bugs.webkit.org/show_bug.cgi?id=89688

Patch by Varun Jain <varunjain@chromium.org> on 2012-07-18
Reviewed by Adam Barth.

.:

* ManualTests/chromium/drag-image-accounts-for-device-scale.html:

Source/WebCore:

Modified ManualTest: ManualTests/chromium/drag-image-accounts-for-device-scale.html

* page/Frame.cpp:
(WebCore::Frame::nodeImage):
(WebCore::Frame::dragImageForSelection):
* platform/chromium/DragImageChromiumSkia.cpp:
(WebCore::dragImageSize):
(WebCore::deleteDragImage):
(WebCore::scaleDragImage):
(WebCore::dissolveDragImageToFraction):
(WebCore::createDragImageFromImage):
* platform/chromium/DragImageRef.h:
(DragImageChromium):
(WebCore):
* platform/graphics/skia/BitmapImageSingleFrameSkia.h:
(BitmapImageSingleFrameSkia):
* platform/graphics/skia/ImageBufferSkia.cpp:
(WebCore::ImageBuffer::ImageBuffer):
(WebCore::ImageBuffer::copyImage):
* platform/graphics/skia/ImageSkia.cpp:
(WebCore::BitmapImageSingleFrameSkia::BitmapImageSingleFrameSkia):
(WebCore::BitmapImageSingleFrameSkia::create):
* platform/graphics/skia/NativeImageSkia.cpp:
(WebCore::NativeImageSkia::NativeImageSkia):
* platform/graphics/skia/NativeImageSkia.h:
(NativeImageSkia):
(WebCore::NativeImageSkia::resolutionScale):

Source/WebKit/chromium:

* src/DragClientImpl.cpp:
(WebKit::DragClientImpl::startDrag):
* tests/DragImageTest.cpp:
(WebCore::TEST):

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

14 files changed:
ChangeLog
ManualTests/chromium/drag-image-accounts-for-device-scale.html
Source/WebCore/ChangeLog
Source/WebCore/page/Frame.cpp
Source/WebCore/platform/chromium/DragImageChromiumSkia.cpp
Source/WebCore/platform/chromium/DragImageRef.h
Source/WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h
Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
Source/WebCore/platform/graphics/skia/ImageSkia.cpp
Source/WebCore/platform/graphics/skia/NativeImageSkia.cpp
Source/WebCore/platform/graphics/skia/NativeImageSkia.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/src/DragClientImpl.cpp
Source/WebKit/chromium/tests/DragImageTest.cpp

index 6c56011..c9b2701 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-07-18  Varun Jain  <varunjain@chromium.org>
+
+        [chromium] Drag image for image elements should be scaled with device scale factor.
+        https://bugs.webkit.org/show_bug.cgi?id=89688
+
+        Reviewed by Adam Barth.
+
+        * ManualTests/chromium/drag-image-accounts-for-device-scale.html:
+
 2012-07-18  Thiago Marcos P. Santos  <thiago.santos@intel.com>
 
         [CMake] Make gtest a shared library
index 1564cae..d8751fb 100644 (file)
@@ -6,5 +6,7 @@
     <div draggable='true' id='dragme'>
         Drag me
     </div>
+    <p>Lastly, for testing dragging of images, drag the image below. If drag image is exactly the same size as the image on the page, the test passes.</p>
+    <img src="../resources/apple.jpg" width="50" height="50">
 </body>
 </html>
index a1a5be5..0c7aea8 100644 (file)
@@ -1,3 +1,38 @@
+2012-07-18  Varun Jain  <varunjain@chromium.org>
+
+        [chromium] Drag image for image elements should be scaled with device scale factor.
+        https://bugs.webkit.org/show_bug.cgi?id=89688
+
+        Reviewed by Adam Barth.
+
+        Modified ManualTest: ManualTests/chromium/drag-image-accounts-for-device-scale.html
+
+        * page/Frame.cpp:
+        (WebCore::Frame::nodeImage):
+        (WebCore::Frame::dragImageForSelection):
+        * platform/chromium/DragImageChromiumSkia.cpp:
+        (WebCore::dragImageSize):
+        (WebCore::deleteDragImage):
+        (WebCore::scaleDragImage):
+        (WebCore::dissolveDragImageToFraction):
+        (WebCore::createDragImageFromImage):
+        * platform/chromium/DragImageRef.h:
+        (DragImageChromium):
+        (WebCore):
+        * platform/graphics/skia/BitmapImageSingleFrameSkia.h:
+        (BitmapImageSingleFrameSkia):
+        * platform/graphics/skia/ImageBufferSkia.cpp:
+        (WebCore::ImageBuffer::ImageBuffer):
+        (WebCore::ImageBuffer::copyImage):
+        * platform/graphics/skia/ImageSkia.cpp:
+        (WebCore::BitmapImageSingleFrameSkia::BitmapImageSingleFrameSkia):
+        (WebCore::BitmapImageSingleFrameSkia::create):
+        * platform/graphics/skia/NativeImageSkia.cpp:
+        (WebCore::NativeImageSkia::NativeImageSkia):
+        * platform/graphics/skia/NativeImageSkia.h:
+        (NativeImageSkia):
+        (WebCore::NativeImageSkia::resolutionScale):
+
 2012-07-18  Yong Li  <yoli@rim.com>
 
         [BlackBerry] Move about: URL handling out of WebCore
index fc3ec9e..5146e73 100644 (file)
@@ -1108,10 +1108,9 @@ DragImageRef Frame::nodeImage(Node* node)
     paintingRect.setWidth(paintingRect.width() * deviceScaleFactor);
     paintingRect.setHeight(paintingRect.height() * deviceScaleFactor);
 
-    OwnPtr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size(), 1, ColorSpaceDeviceRGB));
+    OwnPtr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size(), deviceScaleFactor, ColorSpaceDeviceRGB));
     if (!buffer)
         return 0;
-    buffer->context()->scale(FloatSize(deviceScaleFactor, deviceScaleFactor));
     buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
     buffer->context()->clip(FloatRect(0, 0, paintingRect.maxX(), paintingRect.maxY()));
 
@@ -1138,10 +1137,9 @@ DragImageRef Frame::dragImageForSelection()
     paintingRect.setWidth(paintingRect.width() * deviceScaleFactor);
     paintingRect.setHeight(paintingRect.height() * deviceScaleFactor);
 
-    OwnPtr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size(), 1, ColorSpaceDeviceRGB));
+    OwnPtr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size(), deviceScaleFactor, ColorSpaceDeviceRGB));
     if (!buffer)
         return 0;
-    buffer->context()->scale(FloatSize(deviceScaleFactor, deviceScaleFactor));
     buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
     buffer->context()->clip(FloatRect(0, 0, paintingRect.maxX(), paintingRect.maxY()));
 
index 40f8925..c106c86 100644 (file)
@@ -47,11 +47,12 @@ IntSize dragImageSize(DragImageRef image)
     if (!image)
         return IntSize();
 
-    return IntSize(image->width(), image->height());
+    return IntSize(image->bitmap->width(), image->bitmap->height());
 }
 
 void deleteDragImage(DragImageRef image)
 {
+    delete image->bitmap;
     delete image;
 }
 
@@ -60,13 +61,14 @@ DragImageRef scaleDragImage(DragImageRef image, FloatSize scale)
     if (!image)
         return 0;
 
-    int imageWidth = scale.width() * image->width();
-    int imageHeight = scale.height() * image->height();
-    DragImageRef scaledImage = new SkBitmap(
-        skia::ImageOperations::Resize(*image, skia::ImageOperations::RESIZE_LANCZOS3,
+    int imageWidth = scale.width() * image->bitmap->width();
+    int imageHeight = scale.height() * image->bitmap->height();
+    SkBitmap* scaledImage = new SkBitmap(
+        skia::ImageOperations::Resize(*image->bitmap, skia::ImageOperations::RESIZE_LANCZOS3,
                                       imageWidth, imageHeight));
-    delete image;
-    return scaledImage;
+    delete image->bitmap;
+    image->bitmap = scaledImage;
+    return image;
 }
 
 DragImageRef dissolveDragImageToFraction(DragImageRef image, float fraction)
@@ -74,12 +76,12 @@ DragImageRef dissolveDragImageToFraction(DragImageRef image, float fraction)
     if (!image)
         return 0;
 
-    image->setIsOpaque(false);
-    image->lockPixels();
+    image->bitmap->setIsOpaque(false);
+    image->bitmap->lockPixels();
 
-    for (int row = 0; row < image->height(); ++row) {
-        for (int column = 0; column < image->width(); ++column) {
-            uint32_t* pixel = image->getAddr32(column, row);
+    for (int row = 0; row < image->bitmap->height(); ++row) {
+        for (int column = 0; column < image->bitmap->width(); ++column) {
+            uint32_t* pixel = image->bitmap->getAddr32(column, row);
             *pixel = SkPreMultiplyARGB(SkColorGetA(*pixel) * fraction,
                                        SkColorGetR(*pixel),
                                        SkColorGetG(*pixel),
@@ -87,7 +89,7 @@ DragImageRef dissolveDragImageToFraction(DragImageRef image, float fraction)
         }
     }
 
-    image->unlockPixels();
+    image->bitmap->unlockPixels();
 
     return image;
 }
@@ -103,7 +105,10 @@ DragImageRef createDragImageFromImage(Image* image, RespectImageOrientationEnum)
 
     SkBitmap* dragImage = new SkBitmap();
     bitmap->bitmap().copyTo(dragImage, SkBitmap::kARGB_8888_Config);
-    return dragImage;
+    DragImageChromium* dragImageChromium = new DragImageChromium;
+    dragImageChromium->bitmap = dragImage;
+    dragImageChromium->resolutionScale = bitmap->resolutionScale();
+    return dragImageChromium;
 }
 
 DragImageRef createDragImageIconForCachedImage(CachedImage*)
index 7a6aca8..0d03262 100644 (file)
@@ -33,7 +33,12 @@ class SkBitmap;
 
 namespace WebCore {
 
-typedef SkBitmap* DragImageRef;
+struct DragImageChromium {
+    SkBitmap* bitmap;
+    float resolutionScale;
+};
+
+typedef DragImageChromium* DragImageRef;
 
 } // namespace WebCore
 
index f5203ec..f0d1192 100644 (file)
@@ -49,7 +49,7 @@ public:
     // Creates a new Image from the given SkBitmap.  If "copyPixels" is true, a
     // deep copy is done.  Otherwise, a shallow copy is done (pixel data is
     // ref'ed).
-    static PassRefPtr<BitmapImageSingleFrameSkia> create(const SkBitmap&, bool copyPixels);
+    static PassRefPtr<BitmapImageSingleFrameSkia> create(const SkBitmap&, bool copyPixels, float resolutionScale = 1);
 
     virtual bool isBitmapImage() const;
 
@@ -76,7 +76,7 @@ private:
     NativeImageSkia m_nativeImage;
 
     // Creates a new Image from the given SkBitmap, using a shallow copy.
-    explicit BitmapImageSingleFrameSkia(const SkBitmap&);
+    BitmapImageSingleFrameSkia(const SkBitmap&, float resolutionScale);
 };
 
 FloatRect normalizeRect(const FloatRect&);
index b5490c6..860ff1b 100644 (file)
@@ -108,11 +108,11 @@ static SkCanvas* createNonPlatformCanvas(const IntSize& size)
     return canvas;
 }
 
-ImageBuffer::ImageBuffer(const IntSize& size, float /* resolutionScale */, ColorSpace, RenderingMode renderingMode, DeferralMode deferralMode, bool& success)
+ImageBuffer::ImageBuffer(const IntSize& size, float resolutionScale, ColorSpace, RenderingMode renderingMode, DeferralMode deferralMode, bool& success)
     : m_data(size)
     , m_size(size)
     , m_logicalSize(size)
-    , m_resolutionScale(1)
+    , m_resolutionScale(resolutionScale)
 {
     OwnPtr<SkCanvas> canvas;
 
@@ -133,6 +133,7 @@ ImageBuffer::ImageBuffer(const IntSize& size, float /* resolutionScale */, Color
     m_data.m_platformContext.setCanvas(m_data.m_canvas.get());
     m_context = adoptPtr(new GraphicsContext(&m_data.m_platformContext));
     m_context->platformContext()->setDrawingToImageBuffer(true);
+    m_context->scale(FloatSize(m_resolutionScale, m_resolutionScale));
 
     // Make the background transparent. It would be nice if this wasn't
     // required, but the canvas is currently filled with the magic transparency
@@ -160,7 +161,7 @@ GraphicsContext* ImageBuffer::context() const
 
 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior) const
 {
-    return BitmapImageSingleFrameSkia::create(*m_data.m_platformContext.bitmap(), copyBehavior == CopyBackingStore);
+    return BitmapImageSingleFrameSkia::create(*m_data.m_platformContext.bitmap(), copyBehavior == CopyBackingStore, m_resolutionScale);
 }
 
 PlatformLayer* ImageBuffer::platformLayer() const
index 6a4bcb0..0e87ed9 100644 (file)
@@ -496,20 +496,20 @@ void BitmapImageSingleFrameSkia::draw(GraphicsContext* ctxt,
         observer->didDraw(this);
 }
 
-BitmapImageSingleFrameSkia::BitmapImageSingleFrameSkia(const SkBitmap& bitmap)
-    : m_nativeImage(bitmap)
+BitmapImageSingleFrameSkia::BitmapImageSingleFrameSkia(const SkBitmap& bitmap, float resolutionScale)
+    : m_nativeImage(bitmap, resolutionScale)
 {
 }
 
-PassRefPtr<BitmapImageSingleFrameSkia> BitmapImageSingleFrameSkia::create(const SkBitmap& bitmap, bool copyPixels)
+PassRefPtr<BitmapImageSingleFrameSkia> BitmapImageSingleFrameSkia::create(const SkBitmap& bitmap, bool copyPixels, float resolutionScale)
 {
     if (copyPixels) {
         SkBitmap temp;
         if (!bitmap.deepCopyTo(&temp, bitmap.config()))
             bitmap.copyTo(&temp, bitmap.config());
-        return adoptRef(new BitmapImageSingleFrameSkia(temp));
+        return adoptRef(new BitmapImageSingleFrameSkia(temp, resolutionScale));
     }
-    return adoptRef(new BitmapImageSingleFrameSkia(bitmap));
+    return adoptRef(new BitmapImageSingleFrameSkia(bitmap, resolutionScale));
 }
 
 } // namespace WebCore
index 425f565..7cc23c4 100644 (file)
 namespace WebCore {
 
 NativeImageSkia::NativeImageSkia()
-    : m_resizeRequests(0)
+    : m_resolutionScale(1),
+      m_resizeRequests(0)
 {
 }
 
-NativeImageSkia::NativeImageSkia(const SkBitmap& other)
+NativeImageSkia::NativeImageSkia(const SkBitmap& other, float resolutionScale)
     : m_image(other),
+      m_resolutionScale(resolutionScale),
       m_resizeRequests(0)
 {
 }
index ccfd0aa..2a52e68 100644 (file)
@@ -48,7 +48,7 @@ public:
     // This constructor does a shallow copy of the passed-in SkBitmap (ie., it
     // references the same pixel data and bumps the refcount).  Use only when
     // you want sharing semantics.
-    explicit NativeImageSkia(const SkBitmap&);
+    NativeImageSkia(const SkBitmap&, float resolutionScale);
 
     // Returns the number of bytes of image data. This includes the cached
     // resized version if there is one.
@@ -67,6 +67,8 @@ public:
     const SkBitmap& bitmap() const { return m_image; }
     SkBitmap& bitmap() { return m_image; }
 
+    float resolutionScale() const { return m_resolutionScale; }
+
     // We can keep a resized version of the bitmap cached on this object.
     // This function will return true if there is a cached version of the
     // given image subset with the given dimensions and subsets.
@@ -123,6 +125,7 @@ private:
 
     // The original image.
     SkBitmap m_image;
+    float m_resolutionScale;
 
     // The cached bitmap. This will be empty() if there is no cached image.
     mutable SkBitmap m_resizedImage;
index e1de17d..abf908e 100644 (file)
@@ -1,3 +1,15 @@
+2012-07-18  Varun Jain  <varunjain@chromium.org>
+
+        [chromium] Drag image for image elements should be scaled with device scale factor.
+        https://bugs.webkit.org/show_bug.cgi?id=89688
+
+        Reviewed by Adam Barth.
+
+        * src/DragClientImpl.cpp:
+        (WebKit::DragClientImpl::startDrag):
+        * tests/DragImageTest.cpp:
+        (WebCore::TEST):
+
 2012-07-18  Shawn Singh  <shawnsingh@chromium.org>
 
         [chromium] Fix style for numeric literals in chromium unit test code
index a6fb0bd..3974e7a 100644 (file)
@@ -87,7 +87,13 @@ void DragClientImpl::startDrag(DragImageRef dragImage,
 
     IntSize offsetSize(eventPos - dragImageOrigin);
     WebPoint offsetPoint(offsetSize.width(), offsetSize.height());
-    m_webView->startDragging(frame, dragData, static_cast<WebDragOperationsMask>(dragOperationMask), dragImage ? WebImage(*dragImage) : WebImage(), offsetPoint);
+
+    if (dragImage && dragImage->bitmap && m_webView->deviceScaleFactor() != dragImage->resolutionScale) {
+        ASSERT(dragImage->resolutionScale > 0);
+        float scale = m_webView->deviceScaleFactor() / dragImage->resolutionScale;
+        dragImage = scaleDragImage(dragImage, WebCore::FloatSize(scale, scale));
+    }
+    m_webView->startDragging(frame, dragData, static_cast<WebDragOperationsMask>(dragOperationMask), (dragImage && dragImage->bitmap) ? WebImage(*dragImage->bitmap) : WebImage(), offsetPoint);
 }
 
 void DragClientImpl::dragControllerDestroyed()
index 080607c..f75e85c 100644 (file)
@@ -139,8 +139,8 @@ TEST(DragImageTest, CreateDragImage)
         RefPtr<TestImage> testImage(TestImage::create(IntSize(1, 1)));
         DragImageRef dragImage = createDragImageFromImage(testImage.get());
         ASSERT_TRUE(dragImage);
-        SkAutoLockPixels lock1(*dragImage), lock2(testImage->nativeImageForCurrentFrame()->bitmap());
-        EXPECT_NE(dragImage->getPixels(), testImage->nativeImageForCurrentFrame()->bitmap().getPixels());
+        SkAutoLockPixels lock1(*dragImage->bitmap), lock2(testImage->nativeImageForCurrentFrame()->bitmap());
+        EXPECT_NE(dragImage->bitmap->getPixels(), testImage->nativeImageForCurrentFrame()->bitmap().getPixels());
     }
 }