2
* Copyright (C) 2007 Apple Inc. All rights reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
13
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
#include "DragImage.h"
29
#include "CachedImage.h"
30
#include "GraphicsContext.h"
32
#include "RetainPtr.h"
34
#include <CoreGraphics/CoreGraphics.h>
40
IntSize dragImageSize(DragImageRef image)
45
GetObject(image, sizeof(BITMAP), &b);
46
return IntSize(b.bmWidth, b.bmHeight);
49
void deleteDragImage(DragImageRef image)
52
::DeleteObject(image);
55
HBITMAP allocImage(HDC dc, IntSize size, CGContextRef *targetRef)
58
BITMAPINFO bmpInfo = {0};
59
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
60
bmpInfo.bmiHeader.biWidth = size.width();
61
bmpInfo.bmiHeader.biHeight = size.height();
62
bmpInfo.bmiHeader.biPlanes = 1;
63
bmpInfo.bmiHeader.biBitCount = 32;
64
bmpInfo.bmiHeader.biCompression = BI_RGB;
66
hbmp = CreateDIBSection(dc, &bmpInfo, DIB_RGB_COLORS, &bits, 0, 0);
71
CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
72
CGContextRef bitmapContext = CGBitmapContextCreate(bits, bmpInfo.bmiHeader.biWidth, bmpInfo.bmiHeader.biHeight, 8,
73
bmpInfo.bmiHeader.biWidth * 4, deviceRGB,
74
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
75
CGColorSpaceRelease(deviceRGB);
81
*targetRef = bitmapContext;
85
static CGContextRef createCgContextFromBitmap(HBITMAP bitmap)
88
GetObject(bitmap, sizeof(info), &info);
89
ASSERT(info.bmBitsPixel == 32);
91
CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
92
CGContextRef bitmapContext = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8,
93
info.bmWidthBytes, deviceRGB, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
94
CGColorSpaceRelease(deviceRGB);
98
DragImageRef scaleDragImage(DragImageRef image, FloatSize scale)
100
// FIXME: due to the way drag images are done on windows we need
101
// to preprocess the alpha channel <rdar://problem/5015946>
105
CGContextRef targetContext;
106
CGContextRef srcContext;
108
IntSize srcSize = dragImageSize(image);
109
IntSize dstSize((int)(srcSize.width() * scale.width()), (int)(srcSize.height() * scale.height()));
112
HDC dstDC = CreateCompatibleDC(dc);
116
hbmp = allocImage(dstDC, dstSize, &targetContext);
120
srcContext = createCgContextFromBitmap(image);
121
srcImage = CGBitmapContextCreateImage(srcContext);
126
CGContextDrawImage(targetContext, rect, srcImage);
127
CGImageRelease(srcImage);
128
CGContextRelease(srcContext);
129
CGContextRelease(targetContext);
130
::DeleteObject(image);
142
DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
144
//We don't do this on windows as the dragimage is blended by the OS
148
DragImageRef createDragImageFromImage(Image* img)
152
HDC workingDC = CreateCompatibleDC(dc);
153
CGContextRef drawContext = 0;
157
hbmp = allocImage(workingDC, img->size(), &drawContext);
163
::DeleteObject(hbmp);
167
CGImageRef srcImage = img->getCGImageRef();
169
rect.size = img->size();
171
rect.origin.y = -rect.size.height;
172
static const CGFloat white [] = {1.0, 1.0, 1.0, 1.0};
173
CGContextScaleCTM(drawContext, 1, -1);
174
CGContextSetFillColor(drawContext, white);
175
CGContextFillRect(drawContext, rect);
176
CGContextSetBlendMode(drawContext, kCGBlendModeNormal);
177
CGContextDrawImage(drawContext, rect, srcImage);
178
CGContextRelease(drawContext);
187
DragImageRef createDragImageIconForCachedImage(CachedImage*)
189
//FIXME: Provide icon for image type <rdar://problem/5015949>