REGRESSION (r160152): Selection drag snapshot doesn't appear or has the wrong content...
authorbburg@apple.com <bburg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 9 Jan 2014 21:21:53 +0000 (21:21 +0000)
committerbburg@apple.com <bburg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 9 Jan 2014 21:21:53 +0000 (21:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=125375

Reviewed by Darin Adler.

Source/WebCore:

Move scaling of drag images by the device scale factor out of DragClient
and into WebCore. This removes several redundant copies and scaling operations.

Fix scaling bugs that were cancelled out by over-allocating the backing store.

* page/DragController.cpp:
(WebCore::DragController::startDrag): Scale the drag image for a link
according to the device scale factor before giving it to the OS.

(WebCore::DragController::doImageDrag): Scale the drag image for an image
according to the device scale factor before giving it to the OS.

* page/FrameSnapshotting.cpp:
(WebCore::snapshotFrameRect): Don't pre-scale or clip the snapshot. The
ImageBuffer does this already.

* platform/DragImage.cpp:
(WebCore::createDragImageFromSnapshot): Don't scale the backing store
when copying an ImageBuffer into an Image.

* platform/graphics/cg/ImageBufferCG.cpp:
(WebCore::ImageBuffer::copyImage): Draw the image in user-space coordinates,
not in backing-store coordinates. Remove unnecessary assertions. Crop the
buffer before drawing the image into it.

Source/WebKit2:

Remove scaling from WebDragClient because it is now selectively
performed by WebCore according to the drag image source.

* WebProcess/WebCoreSupport/mac/WebDragClientMac.mm:
(WebKit::WebDragClient::startDrag): Don't scale the provided drag image.

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

Source/WebCore/ChangeLog
Source/WebCore/page/DragController.cpp
Source/WebCore/page/FrameSnapshotting.cpp
Source/WebCore/platform/DragImage.cpp
Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm

index 77636b8..206ac65 100644 (file)
@@ -1,3 +1,35 @@
+2014-01-09  Brian Burg  <bburg@apple.com>
+
+        REGRESSION (r160152): Selection drag snapshot doesn't appear or has the wrong content on Retina
+        https://bugs.webkit.org/show_bug.cgi?id=125375
+
+        Reviewed by Darin Adler.
+
+        Move scaling of drag images by the device scale factor out of DragClient
+        and into WebCore. This removes several redundant copies and scaling operations.
+
+        Fix scaling bugs that were cancelled out by over-allocating the backing store.
+
+        * page/DragController.cpp:
+        (WebCore::DragController::startDrag): Scale the drag image for a link
+        according to the device scale factor before giving it to the OS.
+
+        (WebCore::DragController::doImageDrag): Scale the drag image for an image
+        according to the device scale factor before giving it to the OS.
+
+        * page/FrameSnapshotting.cpp:
+        (WebCore::snapshotFrameRect): Don't pre-scale or clip the snapshot. The
+        ImageBuffer does this already.
+
+        * platform/DragImage.cpp:
+        (WebCore::createDragImageFromSnapshot): Don't scale the backing store
+        when copying an ImageBuffer into an Image.
+
+        * platform/graphics/cg/ImageBufferCG.cpp:
+        (WebCore::ImageBuffer::copyImage): Draw the image in user-space coordinates,
+        not in backing-store coordinates. Remove unnecessary assertions. Crop the
+        buffer before drawing the image into it.
+
 2014-01-09  Myles C. Maxfield  <mmaxfield@apple.com>
 
         Narrow underlines are too tall
index bd31c75..4845a34 100644 (file)
@@ -828,6 +828,8 @@ bool DragController::startDrag(Frame& src, const DragState& state, DragOperation
             IntSize size = dragImageSize(dragImage);
             m_dragOffset = IntPoint(-size.width() / 2, -LinkDragBorderInset);
             dragLoc = IntPoint(mouseDraggedPoint.x() + m_dragOffset.x(), mouseDraggedPoint.y() + m_dragOffset.y());
+            // Later code expects the drag image to be scaled by device's scale factor.
+            dragImage = scaleDragImage(dragImage, FloatSize(m_page.deviceScaleFactor(), m_page.deviceScaleFactor()));
         }
         doSystemDrag(dragImage, dragLoc, mouseDraggedPoint, clipboard, src, true);
     } else if (state.type == DragSourceActionDHTML) {
@@ -869,6 +871,7 @@ void DragController::doImageDrag(Element& element, const IntPoint& dragOrigin, c
         dragImage = fitDragImageToMaxSize(dragImage, layoutRect.size(), maxDragImageSize());
         IntSize fittedSize = dragImageSize(dragImage);
 
+        dragImage = scaleDragImage(dragImage, FloatSize(m_page.deviceScaleFactor(), m_page.deviceScaleFactor()));
         dragImage = dissolveDragImageToFraction(dragImage, DragImageAlpha);
 
         // Properly orient the drag image and orient it differently if it's smaller than the original.
index af45a3c..495406b 100644 (file)
@@ -90,17 +90,12 @@ std::unique_ptr<ImageBuffer> snapshotFrameRect(Frame& frame, const IntRect& imag
     // Other paint behaviors are set by paintContentsForSnapshot.
     frame.view()->setPaintBehavior(paintBehavior);
 
-    float deviceScaleFactor = frame.page()->deviceScaleFactor();
-    IntRect usedRect(imageRect);
-    usedRect.scale(deviceScaleFactor);
-
-    std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(usedRect.size(), deviceScaleFactor, ColorSpaceDeviceRGB);
+    std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(imageRect.size(), frame.page()->deviceScaleFactor(), ColorSpaceDeviceRGB);
     if (!buffer)
         return nullptr;
-    buffer->context()->translate(-usedRect.x(), -usedRect.y());
-    buffer->context()->clip(FloatRect(0, 0, usedRect.maxX(), usedRect.maxY()));
+    buffer->context()->translate(-imageRect.x(), -imageRect.y());
 
-    frame.view()->paintContentsForSnapshot(buffer->context(), usedRect, shouldIncludeSelection, coordinateSpace);
+    frame.view()->paintContentsForSnapshot(buffer->context(), imageRect, shouldIncludeSelection, coordinateSpace);
     return buffer;
 }
 
index f470181..132c1c2 100644 (file)
@@ -108,7 +108,7 @@ static DragImageRef createDragImageFromSnapshot(std::unique_ptr<ImageBuffer> sna
 #else
     UNUSED_PARAM(node);
 #endif
-    RefPtr<Image> image = snapshot->copyImage(ImageBuffer::fastCopyImageMode());
+    RefPtr<Image> image = snapshot->copyImage(ImageBuffer::fastCopyImageMode(), Unscaled);
     if (!image)
         return nullptr;
     return createDragImageFromImage(image.get(), orientation);
index b13d121..231656c 100644 (file)
@@ -212,23 +212,21 @@ static RetainPtr<CGImageRef> createCroppedImageIfNecessary(CGImageRef image, con
 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBehavior scaleBehavior) const
 {
     RetainPtr<CGImageRef> image;
-    if (m_resolutionScale == 1 || scaleBehavior == Unscaled)
+    if (m_resolutionScale == 1 || scaleBehavior == Unscaled) {
         image = copyNativeImage(copyBehavior);
-    else {
+        image = createCroppedImageIfNecessary(image.get(), internalSize());
+    } else {
         image = copyNativeImage(DontCopyBackingStore);
         RetainPtr<CGContextRef> context = adoptCF(CGBitmapContextCreate(0, logicalSize().width(), logicalSize().height(), 8, 4 * logicalSize().width(), deviceRGBColorSpaceRef(), kCGImageAlphaPremultipliedLast));
         CGContextSetBlendMode(context.get(), kCGBlendModeCopy);
-        CGContextDrawImage(context.get(), CGRectMake(0, 0, m_data.m_backingStoreSize.width(), m_data.m_backingStoreSize.height()), image.get());
+        CGContextClipToRect(context.get(), FloatRect(FloatPoint::zero(), logicalSize()));
+        FloatSize imageSizeInUserSpace = scaleSizeToUserSpace(logicalSize(), m_data.m_backingStoreSize, internalSize());
+        CGContextDrawImage(context.get(), FloatRect(FloatPoint::zero(), imageSizeInUserSpace), image.get());
         image = adoptCF(CGBitmapContextCreateImage(context.get()));
     }
-    
-    image = createCroppedImageIfNecessary(image.get(), internalSize());
 
     if (!image)
-        return 0;
-
-    ASSERT(CGImageGetWidth(image.get()) == static_cast<size_t>(m_logicalSize.width()));
-    ASSERT(CGImageGetHeight(image.get()) == static_cast<size_t>(m_logicalSize.height()));
+        return nullptr;
 
     RefPtr<BitmapImage> bitmapImage = BitmapImage::create(image.get());
     bitmapImage->setSpaceSize(spaceSize());
@@ -480,8 +478,8 @@ String ImageBuffer::toDataURL(const String& mimeType, const double* quality, Coo
         RetainPtr<CGContextRef> context = adoptCF(CGBitmapContextCreate(0, logicalSize().width(), logicalSize().height(), 8, 4 * logicalSize().width(), deviceRGBColorSpaceRef(), kCGImageAlphaPremultipliedLast));
         CGContextSetBlendMode(context.get(), kCGBlendModeCopy);
         CGContextClipToRect(context.get(), CGRectMake(0, 0, logicalSize().width(), logicalSize().height()));
-        FloatSize imageRectInUserBounds = scaleSizeToUserSpace(logicalSize(), m_data.m_backingStoreSize, internalSize());
-        CGContextDrawImage(context.get(), CGRectMake(0, 0, imageRectInUserBounds.width(), imageRectInUserBounds.height()), image.get());
+        FloatSize imageSizeInUserSpace = scaleSizeToUserSpace(logicalSize(), m_data.m_backingStoreSize, internalSize());
+        CGContextDrawImage(context.get(), CGRectMake(0, 0, imageSizeInUserSpace.width(), imageSizeInUserSpace.height()), image.get());
         image = adoptCF(CGBitmapContextCreateImage(context.get()));
     }
 
index 5b74e44..e01f0ad 100644 (file)
@@ -1,3 +1,16 @@
+2014-01-09  Brian Burg  <bburg@apple.com>
+
+        REGRESSION (r160152): Selection drag snapshot doesn't appear or has the wrong content on Retina
+        https://bugs.webkit.org/show_bug.cgi?id=125375
+
+        Reviewed by Darin Adler.
+
+        Remove scaling from WebDragClient because it is now selectively
+        performed by WebCore according to the drag image source.
+
+        * WebProcess/WebCoreSupport/mac/WebDragClientMac.mm:
+        (WebKit::WebDragClient::startDrag): Don't scale the provided drag image.
+
 2014-01-09  Tim Horton  <timothy_horton@apple.com>
 
         WebKit2 View Gestures: Support plugins that take over the page scale gesture
index a639192..a5fc6a7 100644 (file)
@@ -79,7 +79,6 @@ static PassRefPtr<ShareableBitmap> convertImageToBitmap(NSImage *image, const In
 void WebDragClient::startDrag(RetainPtr<NSImage> image, const IntPoint& point, const IntPoint&, Clipboard&, Frame& frame, bool linkDrag)
 {
     IntSize bitmapSize([image.get() size]);
-    bitmapSize.scale(frame.page()->deviceScaleFactor());
     RefPtr<ShareableBitmap> bitmap = convertImageToBitmap(image.get(), bitmapSize);
     ShareableBitmap::Handle handle;
     if (!bitmap || !bitmap->createHandle(handle))