summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/win/DragImageCGWin.cpp
diff options
context:
space:
mode:
authorUpstream <upstream-import@none>1970-01-12 13:46:40 +0000
committerUpstream <upstream-import@none>1970-01-12 13:46:40 +0000
commitd8543bb6618c17b12da906afa77d216f58cf4058 (patch)
treec58dc05ed86825bd0ef8d305d58c8205106b540f /WebCore/platform/win/DragImageCGWin.cpp
downloadexternal_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.zip
external_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.tar.gz
external_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.tar.bz2
external/webkit r30707
Diffstat (limited to 'WebCore/platform/win/DragImageCGWin.cpp')
-rw-r--r--WebCore/platform/win/DragImageCGWin.cpp166
1 files changed, 166 insertions, 0 deletions
diff --git a/WebCore/platform/win/DragImageCGWin.cpp b/WebCore/platform/win/DragImageCGWin.cpp
new file mode 100644
index 0000000..7788572
--- /dev/null
+++ b/WebCore/platform/win/DragImageCGWin.cpp
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2007, 2008 Apple 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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 "DragImage.h"
+
+#include "CachedImage.h"
+#include "GraphicsContext.h"
+#include "Image.h"
+#include "RetainPtr.h"
+
+#include <CoreGraphics/CoreGraphics.h>
+
+#include <windows.h>
+
+namespace WebCore {
+
+HBITMAP allocImage(HDC dc, IntSize size, CGContextRef *targetRef)
+{
+ HBITMAP hbmp;
+ BITMAPINFO bmpInfo = {0};
+ bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmpInfo.bmiHeader.biWidth = size.width();
+ bmpInfo.bmiHeader.biHeight = size.height();
+ bmpInfo.bmiHeader.biPlanes = 1;
+ bmpInfo.bmiHeader.biBitCount = 32;
+ bmpInfo.bmiHeader.biCompression = BI_RGB;
+ LPVOID bits;
+ hbmp = CreateDIBSection(dc, &bmpInfo, DIB_RGB_COLORS, &bits, 0, 0);
+
+ if (!targetRef)
+ return hbmp;
+
+ CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
+ CGContextRef bitmapContext = CGBitmapContextCreate(bits, bmpInfo.bmiHeader.biWidth, bmpInfo.bmiHeader.biHeight, 8,
+ bmpInfo.bmiHeader.biWidth * 4, deviceRGB,
+ kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
+ CGColorSpaceRelease(deviceRGB);
+ if (!bitmapContext) {
+ DeleteObject(hbmp);
+ return 0;
+ }
+
+ *targetRef = bitmapContext;
+ return hbmp;
+}
+
+static CGContextRef createCgContextFromBitmap(HBITMAP bitmap)
+{
+ BITMAP info;
+ GetObject(bitmap, sizeof(info), &info);
+ ASSERT(info.bmBitsPixel == 32);
+
+ CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
+ CGContextRef bitmapContext = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8,
+ info.bmWidthBytes, deviceRGB, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
+ CGColorSpaceRelease(deviceRGB);
+ return bitmapContext;
+}
+
+DragImageRef scaleDragImage(DragImageRef image, FloatSize scale)
+{
+ // FIXME: due to the way drag images are done on windows we need
+ // to preprocess the alpha channel <rdar://problem/5015946>
+
+ if (!image)
+ return 0;
+ CGContextRef targetContext;
+ CGContextRef srcContext;
+ CGImageRef srcImage;
+ IntSize srcSize = dragImageSize(image);
+ IntSize dstSize(static_cast<int>(srcSize.width() * scale.width()), static_cast<int>(srcSize.height() * scale.height()));
+ HBITMAP hbmp = 0;
+ HDC dc = GetDC(0);
+ HDC dstDC = CreateCompatibleDC(dc);
+ if (!dstDC)
+ goto exit;
+
+ hbmp = allocImage(dstDC, dstSize, &targetContext);
+ if (!hbmp)
+ goto exit;
+
+ srcContext = createCgContextFromBitmap(image);
+ srcImage = CGBitmapContextCreateImage(srcContext);
+ CGRect rect;
+ rect.origin.x = 0;
+ rect.origin.y = 0;
+ rect.size = dstSize;
+ CGContextDrawImage(targetContext, rect, srcImage);
+ CGImageRelease(srcImage);
+ CGContextRelease(srcContext);
+ CGContextRelease(targetContext);
+ ::DeleteObject(image);
+ image = 0;
+
+exit:
+ if (!hbmp)
+ hbmp = image;
+ if (dstDC)
+ DeleteDC(dstDC);
+ ReleaseDC(0, dc);
+ return hbmp;
+}
+
+DragImageRef createDragImageFromImage(Image* img)
+{
+ HBITMAP hbmp = 0;
+ HDC dc = GetDC(0);
+ HDC workingDC = CreateCompatibleDC(dc);
+ CGContextRef drawContext = 0;
+ if (!workingDC)
+ goto exit;
+
+ hbmp = allocImage(workingDC, img->size(), &drawContext);
+
+ if (!hbmp)
+ goto exit;
+
+ if (!drawContext) {
+ ::DeleteObject(hbmp);
+ hbmp = 0;
+ }
+
+ CGImageRef srcImage = img->getCGImageRef();
+ CGRect rect;
+ rect.size = img->size();
+ rect.origin.x = 0;
+ rect.origin.y = -rect.size.height;
+ static const CGFloat white [] = {1.0, 1.0, 1.0, 1.0};
+ CGContextScaleCTM(drawContext, 1, -1);
+ CGContextSetFillColor(drawContext, white);
+ CGContextFillRect(drawContext, rect);
+ CGContextSetBlendMode(drawContext, kCGBlendModeNormal);
+ CGContextDrawImage(drawContext, rect, srcImage);
+ CGContextRelease(drawContext);
+
+exit:
+ if (workingDC)
+ DeleteDC(workingDC);
+ ReleaseDC(0, dc);
+ return hbmp;
+}
+
+}