summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/win/GraphicsContextWin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics/win/GraphicsContextWin.cpp')
-rw-r--r--WebCore/platform/graphics/win/GraphicsContextWin.cpp120
1 files changed, 96 insertions, 24 deletions
diff --git a/WebCore/platform/graphics/win/GraphicsContextWin.cpp b/WebCore/platform/graphics/win/GraphicsContextWin.cpp
index e4c5b04..54b0cb2 100644
--- a/WebCore/platform/graphics/win/GraphicsContextWin.cpp
+++ b/WebCore/platform/graphics/win/GraphicsContextWin.cpp
@@ -32,6 +32,7 @@
#include "GraphicsContextPlatformPrivateCairo.h"
#endif
+#include "BitmapInfo.h"
#include "TransformationMatrix.h"
#include "NotImplemented.h"
#include "Path.h"
@@ -43,6 +44,14 @@ namespace WebCore {
class SVGResourceImage;
+static void fillWithClearColor(HBITMAP bitmap)
+{
+ BITMAP bmpInfo;
+ GetObject(bitmap, sizeof(bmpInfo), &bmpInfo);
+ int bufferSize = bmpInfo.bmWidthBytes * bmpInfo.bmHeight;
+ memset(bmpInfo.bmBits, 0, bufferSize);
+}
+
bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; }
void GraphicsContext::setShouldIncludeChildWindows(bool include)
@@ -55,6 +64,79 @@ bool GraphicsContext::shouldIncludeChildWindows() const
return m_data->m_shouldIncludeChildWindows;
}
+GraphicsContext::WindowsBitmap::WindowsBitmap(HDC hdc, IntSize size)
+ : m_hdc(0)
+ , m_size(size)
+{
+ BitmapInfo bitmapInfo = BitmapInfo::create(m_size);
+
+ m_bitmap = CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, reinterpret_cast<void**>(&m_bitmapBuffer), 0, 0);
+ if (!m_bitmap)
+ return;
+
+ m_hdc = CreateCompatibleDC(hdc);
+ SelectObject(m_hdc, m_bitmap);
+
+ BITMAP bmpInfo;
+ GetObject(m_bitmap, sizeof(bmpInfo), &bmpInfo);
+ m_bytesPerRow = bmpInfo.bmWidthBytes;
+ m_bitmapBufferLength = bmpInfo.bmWidthBytes * bmpInfo.bmHeight;
+
+ SetGraphicsMode(m_hdc, GM_ADVANCED);
+}
+
+GraphicsContext::WindowsBitmap::~WindowsBitmap()
+{
+ if (!m_bitmap)
+ return;
+
+ DeleteDC(m_hdc);
+ DeleteObject(m_bitmap);
+}
+
+GraphicsContext::WindowsBitmap* GraphicsContext::createWindowsBitmap(IntSize size)
+{
+ return new WindowsBitmap(m_data->m_hdc, size);
+}
+
+HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap)
+{
+ // FIXME: Should a bitmap be created also when a shadow is set?
+ if (mayCreateBitmap && inTransparencyLayer()) {
+ if (dstRect.isEmpty())
+ return 0;
+
+ // Create a bitmap DC in which to draw.
+ BitmapInfo bitmapInfo = BitmapInfo::create(dstRect.size());
+
+ void* pixels = 0;
+ HBITMAP bitmap = ::CreateDIBSection(NULL, &bitmapInfo, DIB_RGB_COLORS, &pixels, 0, 0);
+ if (!bitmap)
+ return 0;
+
+ HDC bitmapDC = ::CreateCompatibleDC(m_data->m_hdc);
+ ::SelectObject(bitmapDC, bitmap);
+
+ // Fill our buffer with clear if we're going to alpha blend.
+ if (supportAlphaBlend)
+ fillWithClearColor(bitmap);
+
+ // Make sure we can do world transforms.
+ SetGraphicsMode(bitmapDC, GM_ADVANCED);
+
+ // Apply a translation to our context so that the drawing done will be at (0,0) of the bitmap.
+ XFORM xform = TransformationMatrix().translate(-dstRect.x(), -dstRect.y());
+
+ ::SetWorldTransform(bitmapDC, &xform);
+
+ return bitmapDC;
+ }
+
+ m_data->flush();
+ m_data->save();
+ return m_data->m_hdc;
+}
+
void GraphicsContextPlatformPrivate::save()
{
if (!m_hdc)
@@ -85,13 +167,8 @@ void GraphicsContextPlatformPrivate::scale(const FloatSize& size)
{
if (!m_hdc)
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;
+
+ XFORM xform = TransformationMatrix().scaleNonUniform(size.width(), size.height());
ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
}
@@ -99,16 +176,7 @@ static const double deg2rad = 0.017453292519943295769; // pi/180
void GraphicsContextPlatformPrivate::rotate(float degreesAngle)
{
- 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;
+ XFORM xform = TransformationMatrix().rotate(degreesAngle);
ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
}
@@ -116,13 +184,17 @@ void GraphicsContextPlatformPrivate::translate(float x , float y)
{
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;
+
+ XFORM xform = TransformationMatrix().translate(x, y);
+ ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
+}
+
+void GraphicsContextPlatformPrivate::concatCTM(const TransformationMatrix& transform)
+{
+ if (!m_hdc)
+ return;
+
+ XFORM xform = transform;
ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
}