summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics/win/GraphicsContextCGWin.cpp')
-rw-r--r--WebCore/platform/graphics/win/GraphicsContextCGWin.cpp114
1 files changed, 52 insertions, 62 deletions
diff --git a/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp b/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
index 58829b5..5a4279a 100644
--- a/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
+++ b/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
@@ -38,7 +38,7 @@ using namespace std;
namespace WebCore {
-static CGContextRef CGContextWithHDC(HDC hdc)
+static CGContextRef CGContextWithHDC(HDC hdc, bool hasAlpha)
{
HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
@@ -46,8 +46,10 @@ static CGContextRef CGContextWithHDC(HDC hdc)
GetObject(bitmap, sizeof(info), &info);
ASSERT(info.bmBitsPixel == 32);
+
+ CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little | (hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst);
CGContextRef context = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8,
- info.bmWidthBytes, deviceRGB, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
+ info.bmWidthBytes, deviceRGB, bitmapInfo);
CGColorSpaceRelease(deviceRGB);
// Flip coords
@@ -60,9 +62,9 @@ static CGContextRef CGContextWithHDC(HDC hdc)
return context;
}
-GraphicsContext::GraphicsContext(HDC hdc)
+GraphicsContext::GraphicsContext(HDC hdc, bool hasAlpha)
: m_common(createGraphicsContextPrivate())
- , m_data(new GraphicsContextPlatformPrivate(CGContextWithHDC(hdc)))
+ , m_data(new GraphicsContextPlatformPrivate(CGContextWithHDC(hdc, hasAlpha)))
{
CGContextRelease(m_data->m_cgContext);
m_data->m_hdc = hdc;
@@ -76,9 +78,12 @@ GraphicsContext::GraphicsContext(HDC hdc)
bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; }
-HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend)
+// FIXME: Is it possible to merge getWindowsContext and createWindowsBitmap into a single API
+// suitable for all clients?
+HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap)
{
- if (inTransparencyLayer()) {
+ // FIXME: Should a bitmap be created also when a shadow is set?
+ if (mayCreateBitmap && inTransparencyLayer()) {
if (dstRect.isEmpty())
return 0;
@@ -133,9 +138,9 @@ HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlpha
return m_data->m_hdc;
}
-void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend)
+void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap)
{
- if (hdc && inTransparencyLayer()) {
+ if (mayCreateBitmap && hdc && inTransparencyLayer()) {
if (dstRect.isEmpty())
return;
@@ -168,75 +173,60 @@ void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, boo
m_data->restore();
}
-void GraphicsContextPlatformPrivate::save()
+GraphicsContext::WindowsBitmap::WindowsBitmap(HDC hdc, IntSize size)
+ : m_hdc(0)
+ , m_size(size)
{
- if (!m_hdc)
+ BITMAPINFO bitmapInfo;
+ bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bitmapInfo.bmiHeader.biWidth = m_size.width();
+ bitmapInfo.bmiHeader.biHeight = m_size.height();
+ bitmapInfo.bmiHeader.biPlanes = 1;
+ bitmapInfo.bmiHeader.biBitCount = 32;
+ bitmapInfo.bmiHeader.biCompression = BI_RGB;
+ bitmapInfo.bmiHeader.biSizeImage = 0;
+ bitmapInfo.bmiHeader.biXPelsPerMeter = 0;
+ bitmapInfo.bmiHeader.biYPelsPerMeter = 0;
+ bitmapInfo.bmiHeader.biClrUsed = 0;
+ bitmapInfo.bmiHeader.biClrImportant = 0;
+
+ m_bitmap = CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, reinterpret_cast<void**>(&m_bitmapBuffer), 0, 0);
+ if (!m_bitmap)
return;
- SaveDC(m_hdc);
-}
-void GraphicsContextPlatformPrivate::restore()
-{
- if (!m_hdc)
- return;
- RestoreDC(m_hdc, -1);
-}
+ m_hdc = CreateCompatibleDC(hdc);
+ SelectObject(m_hdc, m_bitmap);
-void GraphicsContextPlatformPrivate::clip(const IntRect& clipRect)
-{
- if (!m_hdc)
- return;
- IntersectClipRect(m_hdc, clipRect.x(), clipRect.y(), clipRect.right(), clipRect.bottom());
-}
+ BITMAP bmpInfo;
+ GetObject(m_bitmap, sizeof(bmpInfo), &bmpInfo);
+ m_bytesPerRow = bmpInfo.bmWidthBytes;
+ m_bitmapBufferLength = bmpInfo.bmWidthBytes * bmpInfo.bmHeight;
-void GraphicsContextPlatformPrivate::clip(const Path&)
-{
- notImplemented();
+ SetGraphicsMode(m_hdc, GM_ADVANCED);
}
-void GraphicsContextPlatformPrivate::scale(const FloatSize& size)
+GraphicsContext::WindowsBitmap::~WindowsBitmap()
{
- if (!m_hdc)
+ if (!m_bitmap)
return;
- XFORM xform;
- xform.eM11 = size.width();
- xform.eM12 = 0.0f;
- xform.eM21 = 0.0f;
- xform.eM22 = size.height();
- xform.eDx = 0.0f;
- xform.eDy = 0.0f;
- ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
-}
-static const double deg2rad = 0.017453292519943295769; // pi/180
+ DeleteDC(m_hdc);
+ DeleteObject(m_bitmap);
+}
-void GraphicsContextPlatformPrivate::rotate(float degreesAngle)
+GraphicsContext::WindowsBitmap* GraphicsContext::createWindowsBitmap(IntSize size)
{
- float radiansAngle = degreesAngle * deg2rad;
- float cosAngle = cosf(radiansAngle);
- float sinAngle = sinf(radiansAngle);
- XFORM xform;
- xform.eM11 = cosAngle;
- xform.eM12 = -sinAngle;
- xform.eM21 = sinAngle;
- xform.eM22 = cosAngle;
- xform.eDx = 0.0f;
- xform.eDy = 0.0f;
- ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
+ return new WindowsBitmap(m_data->m_hdc, size);
}
-void GraphicsContextPlatformPrivate::translate(float x , float y)
+void GraphicsContext::drawWindowsBitmap(WindowsBitmap* image, const IntPoint& point)
{
- if (!m_hdc)
- return;
- XFORM xform;
- xform.eM11 = 1.0f;
- xform.eM12 = 0.0f;
- xform.eM21 = 0.0f;
- xform.eM22 = 1.0f;
- xform.eDx = x;
- xform.eDy = y;
- ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
+ RetainPtr<CGColorSpaceRef> deviceRGB(AdoptCF, CGColorSpaceCreateDeviceRGB());
+ RetainPtr<CFDataRef> imageData(AdoptCF, CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, image->buffer(), image->bufferLength(), kCFAllocatorNull));
+ RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(imageData.get()));
+ RetainPtr<CGImageRef> cgImage(AdoptCF, CGImageCreate(image->size().width(), image->size().height(), 8, 32, image->bytesPerRow(), deviceRGB.get(),
+ kCGBitmapByteOrder32Little | kCGImageAlphaFirst, dataProvider.get(), 0, true, kCGRenderingIntentDefault));
+ CGContextDrawImage(m_data->m_cgContext, CGRectMake(point.x(), point.y(), image->size().width(), image->size().height()), cgImage.get());
}
void GraphicsContextPlatformPrivate::concatCTM(const AffineTransform& transform)