summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorLouai Al-Khanji <louai.al-khanji@digia.com>2013-12-04 13:40:23 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-10 15:10:29 +0100
commitb9362903b339e57362a7a3296904504521d0e26f (patch)
treeea5f735c17d958fa00f7cf46e40e86be10ed0e26 /src/plugins
parent5a2fc4c367d4645ae3350fdcfb6c1bbd0e9c1a97 (diff)
Add new direct2d platform plugin
This is an alternative plugin for the windows platform. It shares most code with the current windows plugin, but substitutes a direct2d-based paint engine for window backing stores and pixmaps. Change-Id: I78fafd9c5871fa090b49436f5b40ec80f8789f8b Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/direct2d/direct2d.json3
-rw-r--r--src/plugins/platforms/direct2d/direct2d.pro39
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp239
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h76
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp205
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h81
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp218
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h84
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp135
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h95
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h96
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp122
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h78
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp64
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h58
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp131
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h71
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp1116
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h87
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp179
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h85
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp66
-rw-r--r--src/plugins/platforms/platforms.pro4
23 files changed, 3332 insertions, 0 deletions
diff --git a/src/plugins/platforms/direct2d/direct2d.json b/src/plugins/platforms/direct2d/direct2d.json
new file mode 100644
index 0000000000..aaea92f0ef
--- /dev/null
+++ b/src/plugins/platforms/direct2d/direct2d.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "direct2d" ]
+}
diff --git a/src/plugins/platforms/direct2d/direct2d.pro b/src/plugins/platforms/direct2d/direct2d.pro
new file mode 100644
index 0000000000..5a1e71b962
--- /dev/null
+++ b/src/plugins/platforms/direct2d/direct2d.pro
@@ -0,0 +1,39 @@
+TARGET = qdirect2d
+
+PLUGIN_TYPE = platforms
+PLUGIN_CLASS_NAME = QWindowsDirect2DIntegrationPlugin
+load(qt_plugin)
+
+QT *= core-private
+QT *= gui-private
+QT *= platformsupport-private
+
+LIBS *= -ld2d1 -ld3d11 -ldwrite
+
+include(../windows/windows.pri)
+
+SOURCES += \
+ qwindowsdirect2dpaintengine.cpp \
+ qwindowsdirect2dpaintdevice.cpp \
+ qwindowsdirect2dplatformpixmap.cpp \
+ qwindowsdirect2dcontext.cpp \
+ qwindowsdirect2dbitmap.cpp \
+ qwindowsdirect2dbackingstore.cpp \
+ qwindowsdirect2dintegration.cpp \
+ qwindowsdirect2dplatformplugin.cpp \
+ qwindowsdirect2ddevicecontext.cpp \
+ qwindowsdirect2dnativeinterface.cpp
+
+HEADERS += \
+ qwindowsdirect2dpaintengine.h \
+ qwindowsdirect2dpaintdevice.h \
+ qwindowsdirect2dplatformpixmap.h \
+ qwindowsdirect2dcontext.h \
+ qwindowsdirect2dhelpers.h \
+ qwindowsdirect2dbitmap.h \
+ qwindowsdirect2dbackingstore.h \
+ qwindowsdirect2dintegration.h \
+ qwindowsdirect2ddevicecontext.h \
+ qwindowsdirect2dnativeinterface.h
+
+OTHER_FILES += direct2d.json
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp
new file mode 100644
index 0000000000..379e75c26e
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp
@@ -0,0 +1,239 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dbackingstore.h"
+#include "qwindowsdirect2dintegration.h"
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dpaintdevice.h"
+#include "qwindowsdirect2dbitmap.h"
+#include "qwindowsdirect2ddevicecontext.h"
+
+#include "qwindowswindow.h"
+#include "qwindowscontext.h"
+
+#include <QtGui/QWindow>
+#include <QtCore/QDebug>
+
+#include <dxgi1_2.h>
+#include <d3d11.h>
+#include <wrl.h>
+
+using Microsoft::WRL::ComPtr;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DBackingStorePrivate
+{
+public:
+ QWindowsDirect2DBackingStorePrivate() {}
+
+ ComPtr<IDXGISwapChain1> swapChain;
+ QSharedPointer<QWindowsDirect2DBitmap> backingStore;
+ QScopedPointer<QWindowsDirect2DPaintDevice> nativePaintDevice;
+
+ bool init(HWND hwnd)
+ {
+ DXGI_SWAP_CHAIN_DESC1 desc = {};
+
+ desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ desc.SampleDesc.Count = 1;
+ desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ desc.BufferCount = 1;
+ desc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;
+
+ HRESULT hr = QWindowsDirect2DContext::instance()->dxgiFactory()->CreateSwapChainForHwnd(
+ QWindowsDirect2DContext::instance()->d3dDevice(), // [in] IUnknown *pDevice
+ hwnd, // [in] HWND hWnd
+ &desc, // [in] const DXGI_SWAP_CHAIN_DESC1 *pDesc
+ NULL, // [in] const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc
+ NULL, // [in] IDXGIOutput *pRestrictToOutput
+ swapChain.ReleaseAndGetAddressOf()); // [out] IDXGISwapChain1 **ppSwapChain
+
+ if (FAILED(hr))
+ qWarning("%s: Could not create swap chain: %#x", __FUNCTION__, hr);
+
+ return SUCCEEDED(hr);
+ }
+
+ bool setupPaintDevice()
+ {
+ if (!backingStore) {
+ ComPtr<ID2D1DeviceContext> deviceContext;
+ ComPtr<IDXGISurface1> backBufferSurface;
+ ComPtr<ID2D1Bitmap1> backBufferBitmap;
+
+ HRESULT hr = QWindowsDirect2DContext::instance()->d2dDevice()->CreateDeviceContext(
+ D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
+ deviceContext.ReleaseAndGetAddressOf());
+ if (FAILED(hr)) {
+ qWarning("%s: Couldn't create Direct2D Device context: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = swapChain->GetBuffer(0, IID_PPV_ARGS(&backBufferSurface));
+ if (FAILED(hr)) {
+ qWarning("%s: Could not query backbuffer for DXGI Surface: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = deviceContext->CreateBitmapFromDxgiSurface(backBufferSurface.Get(), NULL, backBufferBitmap.ReleaseAndGetAddressOf());
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create Direct2D Bitmap from DXGI Surface: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ backingStore.reset(new QWindowsDirect2DBitmap(backBufferBitmap.Get(), deviceContext.Get()));
+ }
+
+ if (!nativePaintDevice)
+ nativePaintDevice.reset(new QWindowsDirect2DPaintDevice(backingStore.data(), QInternal::Widget));
+
+ return true;
+ }
+
+ void releaseBackingStore()
+ {
+ nativePaintDevice.reset();
+ backingStore.reset();
+ }
+
+ QPaintDevice *paintDevice()
+ {
+ setupPaintDevice();
+ return nativePaintDevice.data();
+ }
+
+ void flush()
+ {
+ swapChain->Present(1, 0);
+ }
+};
+
+/*!
+ \class QWindowsDirect2DBackingStore
+ \brief Backing store for windows.
+ \internal
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsDirect2DBackingStore::QWindowsDirect2DBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+ , d_ptr(new QWindowsDirect2DBackingStorePrivate)
+{
+}
+
+bool QWindowsDirect2DBackingStore::init()
+{
+ if (window()->surfaceType() == QSurface::RasterSurface) {
+ Q_D(QWindowsDirect2DBackingStore);
+ return d->init(windowsWindow()->handle());
+ }
+
+ return true;
+}
+
+QWindowsDirect2DBackingStore *QWindowsDirect2DBackingStore::create(QWindow *window)
+{
+ QWindowsDirect2DBackingStore *result = new QWindowsDirect2DBackingStore(window);
+
+ if (!result->init()) {
+ delete result;
+ result = 0;
+ }
+
+ return result;
+}
+
+QWindowsDirect2DBackingStore::~QWindowsDirect2DBackingStore()
+{
+ Q_D(QWindowsDirect2DBackingStore);
+ d->releaseBackingStore();
+ d->swapChain.Reset();
+}
+
+QPaintDevice *QWindowsDirect2DBackingStore::paintDevice()
+{
+ QPaintDevice *result = 0;
+
+ if (window()->surfaceType() == QSurface::RasterSurface) {
+ Q_D(QWindowsDirect2DBackingStore);
+ result = d->paintDevice();
+ }
+
+ return result;
+}
+
+void QWindowsDirect2DBackingStore::flush(QWindow *, const QRegion &, const QPoint &)
+{
+ if (window()->surfaceType() == QSurface::RasterSurface) {
+ Q_D(QWindowsDirect2DBackingStore);
+ d->flush();
+ }
+}
+
+void QWindowsDirect2DBackingStore::resize(const QSize &size, const QRegion &region)
+{
+ Q_UNUSED(region);
+
+ if (window()->surfaceType() != QSurface::RasterSurface)
+ return;
+
+ Q_D(QWindowsDirect2DBackingStore);
+ d->releaseBackingStore();
+ QWindowsDirect2DContext::instance()->d3dDeviceContext()->ClearState();
+
+ HRESULT hr = d->swapChain->ResizeBuffers(0,
+ size.width(), size.height(),
+ DXGI_FORMAT_UNKNOWN,
+ 0);
+ if (FAILED(hr))
+ qWarning("%s: Could not resize buffers: %#x", __FUNCTION__, hr);
+}
+
+QWindowsWindow *QWindowsDirect2DBackingStore::windowsWindow() const
+{
+ if (const QWindow *w = window())
+ if (QPlatformWindow *pw = w->handle())
+ return static_cast<QWindowsWindow *>(pw);
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h
new file mode 100644
index 0000000000..89ecee67dd
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DBACKINGSTORE_H
+#define QWINDOWSDIRECT2DBACKINGSTORE_H
+
+#include <QtCore/QScopedPointer>
+#include <QtGui/qpa/qplatformbackingstore.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsWindow;
+class QWindowsDirect2DBackingStorePrivate;
+
+class QWindowsDirect2DBackingStore : public QPlatformBackingStore
+{
+ Q_DECLARE_PRIVATE(QWindowsDirect2DBackingStore)
+ Q_DISABLE_COPY(QWindowsDirect2DBackingStore)
+
+public:
+ static QWindowsDirect2DBackingStore *create(QWindow *window);
+ ~QWindowsDirect2DBackingStore();
+
+ QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
+ void flush(QWindow *, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
+ void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE;
+
+private:
+ QWindowsDirect2DBackingStore(QWindow *window);
+ bool init();
+
+ QWindowsWindow *windowsWindow() const;
+ QScopedPointer<QWindowsDirect2DBackingStorePrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DBACKINGSTORE_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
new file mode 100644
index 0000000000..85c56bc73e
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dbitmap.h"
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2ddevicecontext.h"
+
+#include <QtGui/QImage>
+#include <QtGui/QColor>
+
+#include <wrl.h>
+
+using Microsoft::WRL::ComPtr;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DBitmapPrivate
+{
+public:
+ QWindowsDirect2DBitmapPrivate(ID2D1DeviceContext *dc = 0, ID2D1Bitmap1 *bm = 0)
+ : bitmap(bm)
+ , deviceContext(new QWindowsDirect2DDeviceContext(dc))
+ {
+ deviceContext->get()->SetTarget(bm);
+ }
+
+ D2D1_BITMAP_PROPERTIES1 bitmapProperties() const
+ {
+ FLOAT dpiX, dpiY;
+ QWindowsDirect2DContext::instance()->d2dFactory()->GetDesktopDpi(&dpiX, &dpiY);
+
+ return D2D1::BitmapProperties1(
+ D2D1_BITMAP_OPTIONS_TARGET,
+ D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,
+ D2D1_ALPHA_MODE_PREMULTIPLIED),
+ dpiX, dpiY);
+
+ }
+
+ bool resize(int width, int height, const void *data = 0, int pitch = 0)
+ {
+ deviceContext->get()->SetTarget(0);
+ bitmap.Reset();
+
+ D2D1_SIZE_U size = {
+ width, height
+ };
+
+ HRESULT hr = deviceContext->get()->CreateBitmap(size, data, pitch,
+ bitmapProperties(),
+ bitmap.ReleaseAndGetAddressOf());
+ if (SUCCEEDED(hr))
+ deviceContext->get()->SetTarget(bitmap.Get());
+ else
+ qWarning("%s: Could not create bitmap: %#x", __FUNCTION__, hr);
+
+ return SUCCEEDED(hr);
+ }
+
+ QImage toImage(const QRect &rect)
+ {
+ if (!bitmap)
+ return QImage();
+
+ ComPtr<ID2D1Bitmap1> mappingCopy;
+
+ HRESULT hr = S_OK;
+ D2D1_SIZE_U size = bitmap->GetPixelSize();
+
+ D2D1_BITMAP_PROPERTIES1 properties = bitmapProperties();
+ properties.bitmapOptions = D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_CPU_READ;
+
+ hr = deviceContext->get()->CreateBitmap(size, NULL, NULL,
+ properties, &mappingCopy);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create bitmap: %#x", __FUNCTION__, hr);
+ return QImage();
+ }
+
+ hr = mappingCopy->CopyFromBitmap(NULL, bitmap.Get(), NULL);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not copy from bitmap: %#x", __FUNCTION__, hr);
+ return QImage();
+ }
+
+ D2D1_MAPPED_RECT mappedRect;
+ hr = mappingCopy->Map(D2D1_MAP_OPTIONS_READ, &mappedRect);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not map: %#x", __FUNCTION__, hr);
+ return QImage();
+ }
+
+ return QImage(static_cast<const uchar *>(mappedRect.bits),
+ size.width, size.height, mappedRect.pitch,
+ QImage::Format_ARGB32_Premultiplied).copy(rect);
+ }
+
+ QScopedPointer<QWindowsDirect2DDeviceContext> deviceContext;
+ ComPtr<ID2D1Bitmap1> bitmap;
+};
+
+QWindowsDirect2DBitmap::QWindowsDirect2DBitmap()
+ : d_ptr(new QWindowsDirect2DBitmapPrivate)
+{
+}
+
+QWindowsDirect2DBitmap::QWindowsDirect2DBitmap(ID2D1Bitmap1 *bitmap, ID2D1DeviceContext *dc)
+ : d_ptr(new QWindowsDirect2DBitmapPrivate(dc, bitmap))
+{
+}
+
+QWindowsDirect2DBitmap::~QWindowsDirect2DBitmap()
+{
+}
+
+bool QWindowsDirect2DBitmap::resize(int width, int height)
+{
+ Q_D(QWindowsDirect2DBitmap);
+ return d->resize(width, height);
+}
+
+bool QWindowsDirect2DBitmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
+{
+ Q_D(QWindowsDirect2DBitmap);
+
+ QImage converted = image.convertToFormat(QImage::Format_ARGB32_Premultiplied, flags);
+ return d->resize(converted.width(), converted.height(),
+ converted.constBits(), converted.bytesPerLine());
+}
+
+ID2D1Bitmap1* QWindowsDirect2DBitmap::bitmap() const
+{
+ Q_D(const QWindowsDirect2DBitmap);
+ return d->bitmap.Get();
+}
+
+QWindowsDirect2DDeviceContext *QWindowsDirect2DBitmap::deviceContext() const
+{
+ Q_D(const QWindowsDirect2DBitmap);
+ return d->deviceContext.data();
+}
+
+void QWindowsDirect2DBitmap::fill(const QColor &color)
+{
+ Q_D(QWindowsDirect2DBitmap);
+
+ d->deviceContext->begin();
+ d->deviceContext->get()->Clear(to_d2d_color_f(color));
+ d->deviceContext->end();
+}
+
+QImage QWindowsDirect2DBitmap::toImage(const QRect &rect)
+{
+ Q_D(QWindowsDirect2DBitmap);
+ return d->toImage(rect);
+}
+
+QSize QWindowsDirect2DBitmap::size() const
+{
+ Q_D(const QWindowsDirect2DBitmap);
+
+ D2D1_SIZE_U size = d->bitmap->GetPixelSize();
+ return QSize(size.width, size.height);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h
new file mode 100644
index 0000000000..d7015ef342
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DBITMAP_H
+#define QWINDOWSDIRECT2DBITMAP_H
+
+#include <QtCore/QScopedPointer>
+#include <QtGui/QImage>
+
+struct ID2D1DeviceContext;
+struct ID2D1Bitmap1;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DDeviceContext;
+class QWindowsDirect2DBitmapPrivate;
+class QWindowsDirect2DBitmap
+{
+ Q_DECLARE_PRIVATE(QWindowsDirect2DBitmap)
+ Q_DISABLE_COPY(QWindowsDirect2DBitmap)
+public:
+ QWindowsDirect2DBitmap();
+ QWindowsDirect2DBitmap(ID2D1Bitmap1 *bitmap, ID2D1DeviceContext *dc);
+ ~QWindowsDirect2DBitmap();
+
+ bool resize(int width, int height);
+ bool fromImage(const QImage &image, Qt::ImageConversionFlags flags);
+
+ ID2D1Bitmap1* bitmap() const;
+ QWindowsDirect2DDeviceContext* deviceContext() const;
+
+ void fill(const QColor &color);
+ QImage toImage(const QRect &rect = QRect());
+
+ QSize size() const;
+
+private:
+ QScopedPointer<QWindowsDirect2DBitmapPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DBITMAP_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
new file mode 100644
index 0000000000..58002fb0dd
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2dintegration.h"
+
+#include <d3d11_1.h>
+#include <d2d1_1.h>
+#include <d2d1_1helper.h>
+#include <dxgi1_2.h>
+#include <wrl.h>
+#include <dwrite.h>
+
+using Microsoft::WRL::ComPtr;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DContextPrivate
+{
+public:
+ bool init()
+ {
+ HRESULT hr;
+
+ D3D_FEATURE_LEVEL level;
+
+ D3D_DRIVER_TYPE typeAttempts[] = {
+ D3D_DRIVER_TYPE_HARDWARE,
+ D3D_DRIVER_TYPE_WARP
+ };
+ const int ntypes = int(sizeof(typeAttempts) / sizeof(typeAttempts[0]));
+
+ for (int i = 0; i < ntypes; i++) {
+ hr = D3D11CreateDevice(NULL,
+ typeAttempts[i],
+ NULL,
+ D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT,
+ NULL,
+ 0,
+ D3D11_SDK_VERSION,
+ &d3dDevice,
+ &level,
+ &d3dDeviceContext);
+
+ if (SUCCEEDED(hr))
+ break;
+ }
+
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create Direct3D Device: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ ComPtr<IDXGIDevice> dxgiDevice;
+ ComPtr<IDXGIAdapter> dxgiAdapter;
+
+ hr = d3dDevice.As(&dxgiDevice);
+ if (FAILED(hr)) {
+ qWarning("%s: DXGI Device interface query failed on D3D Device: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = dxgiDevice->GetParent(IID_PPV_ARGS(&dxgiAdapter));
+ if (FAILED(hr)) {
+ qWarning("%s: Failed to probe DXGI Device for parent DXGI Adapter: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory));
+ if (FAILED(hr)) {
+ qWarning("%s: Failed to probe DXGI Adapter for parent DXGI Factory: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ D2D1_FACTORY_OPTIONS options = {};
+
+#ifdef QT_D2D_DEBUG_OUTPUT
+ qDebug("Turning on Direct2D debugging messages");
+ options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
+#endif // QT_D2D_DEBUG_OUTPUT
+
+ hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, options, d2dFactory.GetAddressOf());
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create Direct2D Factory: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = d2dFactory->CreateDevice(dxgiDevice.Get(), &d2dDevice);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create D2D Device: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory),
+ static_cast<IUnknown **>(&directWriteFactory));
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create DirectWrite factory: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = directWriteFactory->GetGdiInterop(&directWriteGdiInterop);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create DirectWrite GDI Interop: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ return true;
+ }
+
+ ComPtr<ID3D11Device> d3dDevice;
+ ComPtr<ID2D1Factory1> d2dFactory;
+ ComPtr<ID2D1Device> d2dDevice;
+ ComPtr<IDXGIFactory2> dxgiFactory;
+ ComPtr<ID3D11DeviceContext> d3dDeviceContext;
+ ComPtr<IDWriteFactory> directWriteFactory;
+ ComPtr<IDWriteGdiInterop> directWriteGdiInterop;
+};
+
+QWindowsDirect2DContext::QWindowsDirect2DContext()
+ : d_ptr(new QWindowsDirect2DContextPrivate)
+{
+}
+
+QWindowsDirect2DContext::~QWindowsDirect2DContext() {}
+
+bool QWindowsDirect2DContext::init()
+{
+ Q_D(QWindowsDirect2DContext);
+ return d->init();
+}
+
+QWindowsDirect2DContext *QWindowsDirect2DContext::instance()
+{
+ return QWindowsDirect2DIntegration::instance()->direct2DContext();
+}
+
+ID3D11Device *QWindowsDirect2DContext::d3dDevice() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->d3dDevice.Get();
+}
+
+ID2D1Device *QWindowsDirect2DContext::d2dDevice() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->d2dDevice.Get();
+}
+
+ID2D1Factory1 *QWindowsDirect2DContext::d2dFactory() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->d2dFactory.Get();
+}
+
+IDXGIFactory2 *QWindowsDirect2DContext::dxgiFactory() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->dxgiFactory.Get();
+}
+
+ID3D11DeviceContext *QWindowsDirect2DContext::d3dDeviceContext() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->d3dDeviceContext.Get();
+}
+
+IDWriteFactory *QWindowsDirect2DContext::dwriteFactory() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->directWriteFactory.Get();
+}
+
+IDWriteGdiInterop *QWindowsDirect2DContext::dwriteGdiInterop() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->directWriteGdiInterop.Get();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
new file mode 100644
index 0000000000..0025463dd5
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DCONTEXT_H
+#define QWINDOWSDIRECT2DCONTEXT_H
+
+#include <QtCore/QScopedPointer>
+
+struct ID3D11Device;
+struct ID2D1Device;
+struct ID2D1Factory1;
+struct IDXGIFactory2;
+struct ID3D11DeviceContext;
+struct IDWriteFactory;
+struct IDWriteGdiInterop;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DContextPrivate;
+class QWindowsDirect2DContext
+{
+ Q_DECLARE_PRIVATE( QWindowsDirect2DContext )
+
+public:
+ QWindowsDirect2DContext();
+ virtual ~QWindowsDirect2DContext();
+
+ bool init();
+
+ static QWindowsDirect2DContext *instance();
+
+ ID3D11Device *d3dDevice() const;
+ ID2D1Device *d2dDevice() const;
+ ID2D1Factory1 *d2dFactory() const;
+ IDXGIFactory2 *dxgiFactory() const;
+ ID3D11DeviceContext *d3dDeviceContext() const;
+ IDWriteFactory *dwriteFactory() const;
+ IDWriteGdiInterop *dwriteGdiInterop() const;
+
+private:
+ QScopedPointer<QWindowsDirect2DContextPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DCONTEXT_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
new file mode 100644
index 0000000000..3ff4c9e636
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2ddevicecontext.h"
+
+#include <wrl.h>
+
+using Microsoft::WRL::ComPtr;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DDeviceContextPrivate {
+public:
+ QWindowsDirect2DDeviceContextPrivate(ID2D1DeviceContext *dc)
+ : deviceContext(dc)
+ , refCount(0)
+ {
+ if (!dc) {
+ HRESULT hr = QWindowsDirect2DContext::instance()->d2dDevice()->CreateDeviceContext(
+ D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
+ &deviceContext);
+ if (FAILED(hr))
+ qFatal("%s: Couldn't create Direct2D Device Context: %#x", __FUNCTION__, hr);
+ }
+
+ Q_ASSERT(deviceContext);
+ }
+
+ void begin()
+ {
+ Q_ASSERT(deviceContext);
+ Q_ASSERT(refCount >= 0);
+
+ if (refCount == 0)
+ deviceContext->BeginDraw();
+
+ refCount++;
+ }
+
+ bool end()
+ {
+ Q_ASSERT(deviceContext);
+ Q_ASSERT(refCount >= 0);
+
+ bool success = true;
+ refCount--;
+
+ if (refCount == 0) {
+ D2D1_TAG tag1, tag2;
+ HRESULT hr = deviceContext->EndDraw(&tag1, &tag2);
+
+ if (FAILED(hr)) {
+ success = false;
+ qWarning("%s: EndDraw failed: %#x, tag1: %lld, tag2: %lld", __FUNCTION__, hr, tag1, tag2);
+ }
+ }
+
+ return success;
+ }
+
+ ComPtr<ID2D1DeviceContext> deviceContext;
+ int refCount;
+};
+
+QWindowsDirect2DDeviceContext::QWindowsDirect2DDeviceContext(ID2D1DeviceContext *dc)
+ : d_ptr(new QWindowsDirect2DDeviceContextPrivate(dc))
+{
+}
+
+QWindowsDirect2DDeviceContext::~QWindowsDirect2DDeviceContext()
+{
+
+}
+
+ID2D1DeviceContext *QWindowsDirect2DDeviceContext::get() const
+{
+ Q_D(const QWindowsDirect2DDeviceContext);
+ Q_ASSERT(d->deviceContext);
+
+ return d->deviceContext.Get();
+}
+
+void QWindowsDirect2DDeviceContext::begin()
+{
+ Q_D(QWindowsDirect2DDeviceContext);
+ d->begin();
+}
+
+bool QWindowsDirect2DDeviceContext::end()
+{
+ Q_D(QWindowsDirect2DDeviceContext);
+ return d->end();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h
new file mode 100644
index 0000000000..4986efb967
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DDEVICECONTEXT_H
+#define QWINDOWSDIRECT2DDEVICECONTEXT_H
+
+#include "qwindowsdirect2dhelpers.h"
+
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+/*
+ * Convenience class for handling device contexts. We have to call BeginDraw
+ * before anything can happen, and EndDraw once we're done, for every frame and
+ * pretty much any kind of operation.
+ *
+ * Unfortunately, these calls cannot be interleaved, and there is no way to check
+ * what state a device context is in.
+ *
+ * The end result is that the following throws an error if we don't track it:
+ * QPixmap pmap;
+ * QPainter painter(&pmap);
+ * pmap.clear();
+ *
+ * Here BeginDraw would first be called through the paint device, then when we clear
+ * the pixmap we would have to call it again. There is no way to know what state
+ * the device context is in when performing the clear, and activating the dc is an
+ * error. Bummer.
+ *
+ * Hence we keep a reference count here and only activate/deactivate the device
+ * if the refcount is zero.
+ *
+ * In a nutshell: Do not call BeginDraw/EndDraw yourself on the device pointer, do
+ * so through the begin/end members below.
+ */
+
+class QWindowsDirect2DDeviceContextPrivate;
+class QWindowsDirect2DDeviceContext
+{
+ Q_DECLARE_PRIVATE(QWindowsDirect2DDeviceContext)
+public:
+ QWindowsDirect2DDeviceContext(ID2D1DeviceContext *dc);
+ ~QWindowsDirect2DDeviceContext();
+
+ ID2D1DeviceContext *get() const;
+
+ void begin();
+ bool end();
+
+private:
+ QScopedPointer<QWindowsDirect2DDeviceContextPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DDEVICECONTEXT_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h b/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h
new file mode 100644
index 0000000000..0ca26ca4cb
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DHELPERS_H
+#define QWINDOWSDIRECT2DHELPERS_H
+
+#include <QtCore/QRectF>
+#include <QtCore/QSizeF>
+#include <QtCore/QPointF>
+#include <QtGui/QColor>
+#include <QtGui/QTransform>
+
+#include <d2d1_1helper.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECL_CONSTEXPR inline D2D1_RECT_U to_d2d_rect_u(const QRect &qrect)
+{
+ return D2D1::RectU(qrect.left(), qrect.top(), qrect.right(), qrect.bottom());
+}
+
+Q_DECL_CONSTEXPR inline D2D1_RECT_F to_d2d_rect_f(const QRectF &qrect)
+{
+ return D2D1::RectF(qrect.left(), qrect.top(), qrect.right(), qrect.bottom());
+}
+
+Q_DECL_CONSTEXPR inline D2D1_SIZE_U to_d2d_size_u(const QSizeF &qsize)
+{
+ return D2D1::SizeU(qsize.width(), qsize.height());
+}
+
+Q_DECL_CONSTEXPR inline D2D1_SIZE_U to_d2d_size_u(const QSize &qsize)
+{
+ return D2D1::SizeU(qsize.width(), qsize.height());
+}
+
+Q_DECL_CONSTEXPR inline D2D1_POINT_2F to_d2d_point_2f(const QPointF &qpoint)
+{
+ return D2D1::Point2F(qpoint.x(), qpoint.y());
+}
+
+Q_DECL_CONSTEXPR inline D2D1::ColorF to_d2d_color_f(const QColor &c)
+{
+ return D2D1::ColorF(c.redF(), c.greenF(), c.blueF(), c.alphaF());
+}
+
+Q_DECL_CONSTEXPR inline D2D1_MATRIX_3X2_F to_d2d_matrix_3x2_f(const QTransform &transform)
+{
+ Q_ASSERT(transform.isAffine());
+
+ return D2D1::Matrix3x2F(transform.m11(), transform.m12(),
+ transform.m21(), transform.m22(),
+ transform.m31(), transform.m32());
+}
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DHELPERS_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
new file mode 100644
index 0000000000..c2f3c05bde
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dintegration.h"
+#include "qwindowsdirect2dbackingstore.h"
+#include "qwindowsdirect2dplatformpixmap.h"
+#include "qwindowsdirect2dnativeinterface.h"
+
+#include "qwindowscontext.h"
+
+#include <QtCore/QDebug>
+#include <QtGui/private/qpixmap_raster_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DIntegrationPrivate
+{
+public:
+ QWindowsDirect2DNativeInterface m_nativeInterface;
+ QWindowsDirect2DContext m_d2dContext;
+};
+
+QWindowsDirect2DIntegration *QWindowsDirect2DIntegration::create(const QStringList &paramList)
+{
+ QWindowsDirect2DIntegration *integration = new QWindowsDirect2DIntegration(paramList);
+
+ if (!integration->init()) {
+ delete integration;
+ integration = 0;
+ }
+
+ return integration;
+}
+
+QWindowsDirect2DIntegration::~QWindowsDirect2DIntegration()
+{
+
+}
+
+ QWindowsDirect2DIntegration *QWindowsDirect2DIntegration::instance()
+ {
+ return static_cast<QWindowsDirect2DIntegration *>(QWindowsIntegration::instance());
+ }
+
+ QPlatformNativeInterface *QWindowsDirect2DIntegration::nativeInterface() const
+ {
+ return &d->m_nativeInterface;
+ }
+
+QPlatformPixmap *QWindowsDirect2DIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
+{
+ switch (type) {
+ case QPlatformPixmap::BitmapType:
+ return new QRasterPlatformPixmap(type);
+ break;
+ default:
+ return new QWindowsDirect2DPlatformPixmap(type);
+ break;
+ }
+}
+
+QPlatformBackingStore *QWindowsDirect2DIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ return QWindowsDirect2DBackingStore::create(window);
+}
+
+QWindowsDirect2DContext *QWindowsDirect2DIntegration::direct2DContext() const
+{
+ return &d->m_d2dContext;
+}
+
+QWindowsDirect2DIntegration::QWindowsDirect2DIntegration(const QStringList &paramList)
+ : QWindowsIntegration(paramList)
+ , d(new QWindowsDirect2DIntegrationPrivate)
+{
+}
+
+bool QWindowsDirect2DIntegration::init()
+{
+ return d->m_d2dContext.init();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h
new file mode 100644
index 0000000000..12412cbc0f
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DINTEGRATION_H
+#define QWINDOWSDIRECT2DINTEGRATION_H
+
+#include "qwindowsintegration.h"
+
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DContext;
+class QWindowsDirect2DIntegrationPrivate;
+
+class QWindowsDirect2DIntegration : public QWindowsIntegration
+{
+public:
+ static QWindowsDirect2DIntegration *create(const QStringList &paramList);
+
+ virtual ~QWindowsDirect2DIntegration();
+
+ static QWindowsDirect2DIntegration *instance();
+
+ QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+
+ QWindowsDirect2DContext *direct2DContext() const;
+
+private:
+ explicit QWindowsDirect2DIntegration(const QStringList &paramList);
+ bool init();
+
+ QScopedPointer<QWindowsDirect2DIntegrationPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DINTEGRATION_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp
new file mode 100644
index 0000000000..6792d92de5
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dnativeinterface.h"
+
+#include <QtGui/QBackingStore>
+
+QT_BEGIN_NAMESPACE
+
+void *QWindowsDirect2DNativeInterface::nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs)
+{
+ if (!bs || !bs->handle()) {
+ qWarning("%s: '%s' requested for null backingstore or backingstore without handle.", __FUNCTION__, resource.constData());
+ return 0;
+ }
+
+ // getDC is so common we don't want to print an "invalid key" line for it
+ if (resource == "getDC")
+ return 0;
+
+ qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
+ return 0;
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h
new file mode 100644
index 0000000000..ee3f7f6eed
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DNATIVEINTERFACE_H
+#define QWINDOWSDIRECT2DNATIVEINTERFACE_H
+
+#include "qwindowsnativeinterface.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DNativeInterface : public QWindowsNativeInterface
+{
+ Q_OBJECT
+public:
+ void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs) Q_DECL_OVERRIDE;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
new file mode 100644
index 0000000000..85dbaab2ce
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dpaintdevice.h"
+#include "qwindowsdirect2dpaintengine.h"
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2dbitmap.h"
+#include "qwindowsdirect2ddevicecontext.h"
+
+#include "qwindowswindow.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DPaintDevicePrivate
+{
+public:
+ QWindowsDirect2DPaintDevicePrivate(QWindowsDirect2DBitmap *bitmap, QInternal::PaintDeviceFlags f)
+ : engine(new QWindowsDirect2DPaintEngine(bitmap))
+ , bitmap(bitmap)
+ , flags(f)
+ {}
+
+ QScopedPointer<QWindowsDirect2DPaintEngine> engine;
+ QWindowsDirect2DBitmap *bitmap;
+ QInternal::PaintDeviceFlags flags;
+};
+
+QWindowsDirect2DPaintDevice::QWindowsDirect2DPaintDevice(QWindowsDirect2DBitmap *bitmap, QInternal::PaintDeviceFlags flags)
+ : d_ptr(new QWindowsDirect2DPaintDevicePrivate(bitmap, flags))
+{
+}
+
+QPaintEngine *QWindowsDirect2DPaintDevice::paintEngine() const
+{
+ Q_D(const QWindowsDirect2DPaintDevice);
+
+ return d->engine.data();
+}
+
+int QWindowsDirect2DPaintDevice::devType() const
+{
+ Q_D(const QWindowsDirect2DPaintDevice);
+
+ return d->flags;
+}
+
+int QWindowsDirect2DPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
+{
+ Q_D(const QWindowsDirect2DPaintDevice);
+
+ switch (metric) {
+ case QPaintDevice::PdmWidth:
+ return d->bitmap->bitmap()->GetPixelSize().width;
+ break;
+ case QPaintDevice::PdmHeight:
+ return d->bitmap->bitmap()->GetPixelSize().height;
+ break;
+ case QPaintDevice::PdmNumColors:
+ return INT_MAX;
+ break;
+ case QPaintDevice::PdmDepth:
+ return 32;
+ break;
+ case QPaintDevice::PdmDpiX:
+ case QPaintDevice::PdmPhysicalDpiX:
+ {
+ FLOAT x, y;
+ QWindowsDirect2DContext::instance()->d2dFactory()->GetDesktopDpi(&x, &y);
+ return x;
+ }
+ break;
+ case QPaintDevice::PdmDpiY:
+ case QPaintDevice::PdmPhysicalDpiY:
+ {
+ FLOAT x, y;
+ QWindowsDirect2DContext::instance()->d2dFactory()->GetDesktopDpi(&x, &y);
+ return y;
+ }
+ break;
+ case QPaintDevice::PdmDevicePixelRatio:
+ return 1;
+ break;
+ case QPaintDevice::PdmWidthMM:
+ case QPaintDevice::PdmHeightMM:
+ return -1;
+ break;
+ }
+
+ return -1;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h
new file mode 100644
index 0000000000..c799083d84
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DPAINTDEVICE_H
+#define QWINDOWSDIRECT2DPAINTDEVICE_H
+
+#include <QtCore/QScopedPointer>
+#include <QtGui/QPaintDevice>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DBitmap;
+
+class QWindowsDirect2DPaintDevicePrivate;
+class QWindowsDirect2DPaintDevice : public QPaintDevice
+{
+ Q_DECLARE_PRIVATE(QWindowsDirect2DPaintDevice)
+
+public:
+ QWindowsDirect2DPaintDevice(QWindowsDirect2DBitmap *bitmap, QInternal::PaintDeviceFlags flags);
+ QPaintEngine *paintEngine() const Q_DECL_OVERRIDE;
+ int devType() const Q_DECL_OVERRIDE;
+
+protected:
+ int metric(PaintDeviceMetric metric) const Q_DECL_OVERRIDE;
+
+private:
+ QScopedPointer<QWindowsDirect2DPaintDevicePrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DPAINTDEVICE_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
new file mode 100644
index 0000000000..aad3d192e7
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
@@ -0,0 +1,1116 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dpaintengine.h"
+#include "qwindowsdirect2dplatformpixmap.h"
+#include "qwindowsdirect2dpaintdevice.h"
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2dbitmap.h"
+#include "qwindowsdirect2ddevicecontext.h"
+
+#include "qwindowsfontengine.h"
+#include "qwindowsfontenginedirectwrite.h"
+#include "qwindowsfontdatabase.h"
+#include "qwindowsintegration.h"
+
+#include <QtCore/QStack>
+#include <QtGui/private/qpaintengine_p.h>
+#include <QtGui/private/qtextengine_p.h>
+#include <QtGui/private/qfontengine_p.h>
+
+#include <dwrite_1.h>
+#include <wrl.h>
+
+using Microsoft::WRL::ComPtr;
+
+QT_BEGIN_NAMESPACE
+
+enum {
+ D2DDebugDrawInitialStateTag = -1,
+ D2DDebugDrawEllipseTag = 1,
+ D2DDebugDrawImageTag,
+ D2DDebugDrawLinesTag,
+ D2DDebugDrawPathTag,
+ D2DDebugDrawPixmapTag,
+ D2DDebugDrawPointsTag,
+ D2DDebugDrawPolygonTag,
+ D2DDebugDrawRectsTag,
+ D2DDebugDrawTextItemTag,
+ D2DDebugDrawTiledPixmap
+};
+#define D2D_TAG(tag) d->dc()->SetTags(tag, tag)
+
+Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert);
+
+static inline ID2D1Factory1 *factory()
+{
+ return QWindowsDirect2DContext::instance()->d2dFactory();
+}
+
+static const qreal defaultOpacity = 1.0;
+static const qreal defaultPenWidth = 1.0;
+
+static ComPtr<ID2D1PathGeometry> painterPathToPathGeometry(const QPainterPath &path)
+{
+ ComPtr<ID2D1PathGeometry> geometry;
+ ComPtr<ID2D1GeometrySink> sink;
+
+ HRESULT hr = factory()->CreatePathGeometry(&geometry);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create path geometry: %#x", __FUNCTION__, hr);
+ return NULL;
+ }
+
+ hr = geometry->Open(&sink);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create geometry sink: %#x", __FUNCTION__, hr);
+ return NULL;
+ }
+
+ switch (path.fillRule()) {
+ case Qt::WindingFill:
+ sink->SetFillMode(D2D1_FILL_MODE_WINDING);
+ break;
+ case Qt::OddEvenFill:
+ sink->SetFillMode(D2D1_FILL_MODE_ALTERNATE);
+ break;
+ }
+
+ bool inFigure = false;
+
+ for (int i = 0; i < path.elementCount(); i++) {
+ const QPainterPath::Element element = path.elementAt(i);
+
+ switch (element.type) {
+ case QPainterPath::MoveToElement:
+ if (inFigure)
+ sink->EndFigure(D2D1_FIGURE_END_OPEN);
+
+ sink->BeginFigure(to_d2d_point_2f(element), D2D1_FIGURE_BEGIN_FILLED);
+ inFigure = true;
+ break;
+
+ case QPainterPath::LineToElement:
+ sink->AddLine(to_d2d_point_2f(element));
+ break;
+
+ case QPainterPath::CurveToElement:
+ {
+ const QPainterPath::Element data1 = path.elementAt(++i);
+ const QPainterPath::Element data2 = path.elementAt(++i);
+
+ Q_ASSERT(i < path.elementCount());
+
+ Q_ASSERT(data1.type == QPainterPath::CurveToDataElement);
+ Q_ASSERT(data2.type == QPainterPath::CurveToDataElement);
+
+ D2D1_BEZIER_SEGMENT segment;
+
+ segment.point1 = to_d2d_point_2f(element);
+ segment.point2 = to_d2d_point_2f(data1);
+ segment.point3 = to_d2d_point_2f(data2);
+
+ sink->AddBezier(segment);
+ }
+ break;
+
+ case QPainterPath::CurveToDataElement:
+ qWarning("%s: Unhandled Curve Data Element", __FUNCTION__);
+ break;
+ }
+ }
+
+ if (inFigure)
+ sink->EndFigure(D2D1_FIGURE_END_OPEN);
+
+ sink->Close();
+
+ return geometry;
+}
+
+static ComPtr<ID2D1PathGeometry> regionToPathGeometry(const QRegion &region)
+{
+ QPainterPath ppath;
+ ppath.addRegion(region);
+ return painterPathToPathGeometry(ppath);
+}
+
+class QWindowsDirect2DPaintEnginePrivate : public QPaintEnginePrivate
+{
+ Q_DECLARE_PUBLIC(QWindowsDirect2DPaintEngine)
+public:
+ QWindowsDirect2DPaintEnginePrivate(QWindowsDirect2DBitmap *bm)
+ : bitmap(bm)
+ , clipPushed(false)
+ , hasPerspectiveTransform(false)
+ , opacity(1.0)
+ , renderHints(QPainter::TextAntialiasing)
+ {
+ pen.reset();
+
+ HRESULT hr = factory()->CreateStrokeStyle(D2D1::StrokeStyleProperties(D2D1_CAP_STYLE_ROUND,
+ D2D1_CAP_STYLE_ROUND,
+ D2D1_CAP_STYLE_ROUND),
+ NULL, 0,
+ pointStrokeStyle.ReleaseAndGetAddressOf());
+ if (FAILED(hr))
+ qWarning("%s: Could not create stroke style for points and zero length lines: %#x", __FUNCTION__, hr);
+
+ dc()->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
+ }
+
+ QWindowsDirect2DBitmap *bitmap;
+
+ QPainterPath clipPath;
+ bool clipPushed;
+
+ ComPtr<ID2D1StrokeStyle> pointStrokeStyle;
+ QPointF currentBrushOrigin;
+
+ bool hasPerspectiveTransform;
+
+ qreal opacity;
+
+ struct {
+ qreal width;
+ QColor color;
+ bool isNull;
+ ComPtr<ID2D1Brush> brush;
+ ComPtr<ID2D1StrokeStyle1> strokeStyle;
+
+ inline void reset() {
+ width = defaultPenWidth;
+ color = QColor(Qt::black);
+ isNull = true;
+ brush.Reset();
+ strokeStyle.Reset();
+ }
+ } pen;
+
+ struct {
+ ComPtr<ID2D1Brush> brush;
+ } brush;
+
+ QPainter::RenderHints renderHints;
+
+ inline ID2D1DeviceContext *dc() const
+ {
+ Q_ASSERT(bitmap);
+ return bitmap->deviceContext()->get();
+ }
+
+ inline D2D1_INTERPOLATION_MODE interpolationMode() const
+ {
+ return (renderHints & QPainter::SmoothPixmapTransform) ? D2D1_INTERPOLATION_MODE_HIGH_QUALITY_CUBIC
+ : D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
+ }
+
+ inline D2D1_ANTIALIAS_MODE antialiasMode() const
+ {
+ return (renderHints & QPainter::Antialiasing) ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
+ : D2D1_ANTIALIAS_MODE_ALIASED;
+ }
+
+ void updateState(const QPaintEngineState &state, QPaintEngine::DirtyFlags dirty)
+ {
+ if (dirty & QPaintEngine::DirtyPen)
+ updatePen(state.pen());
+
+ if (dirty & QPaintEngine::DirtyBrush)
+ updateBrush(state.brush());
+
+ if (dirty & QPaintEngine::DirtyBrushOrigin)
+ updateBrushOrigin(state.brushOrigin());
+
+ if (dirty & QPaintEngine::DirtyHints)
+ updateHints(state.renderHints());
+
+ if (dirty & QPaintEngine::DirtyTransform)
+ updateTransform(state.transform());
+
+ if (dirty & QPaintEngine::DirtyClipEnabled)
+ updateClipEnabled(state.isClipEnabled());
+
+ if (dirty & QPaintEngine::DirtyClipPath)
+ updateClipPath(state.clipPath(), state.clipOperation());
+
+ if (dirty & QPaintEngine::DirtyClipRegion)
+ updateClipRegion(state.clipRegion(), state.clipOperation());
+
+ if (dirty & QPaintEngine::DirtyOpacity)
+ updateOpacity(state.opacity());
+ }
+
+ void updateTransform(const QTransform &t)
+ {
+ dc()->SetTransform(to_d2d_matrix_3x2_f(t));
+ hasPerspectiveTransform = !t.isAffine();
+ }
+
+ void updateOpacity(qreal o)
+ {
+ opacity = o;
+ if (brush.brush)
+ brush.brush.Get()->SetOpacity(o);
+ if (pen.brush)
+ pen.brush.Get()->SetOpacity(o);
+ }
+
+ void pushClip()
+ {
+ ComPtr<ID2D1Geometry> geometricMask = painterPathToPathGeometry(clipPath);
+ if (!geometricMask) {
+ qWarning("%s: Could not convert painter path, not pushing clip path!", __FUNCTION__);
+ return;
+ }
+
+ popClip();
+ dc()->PushLayer(D2D1::LayerParameters1(D2D1::InfiniteRect(),
+ geometricMask.Get(),
+ antialiasMode(),
+ D2D1::IdentityMatrix(),
+ 1.0,
+ NULL,
+ D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND),
+ NULL);
+ clipPushed = true;
+ }
+
+ void popClip()
+ {
+ if (clipPushed) {
+ dc()->PopLayer();
+ clipPushed = false;
+ }
+ }
+
+ void updateClipEnabled(bool enabled)
+ {
+ if (!enabled)
+ popClip();
+ else if (!clipPushed)
+ pushClip();
+ }
+
+ void updateClipPath(const QPainterPath &path, Qt::ClipOperation operation)
+ {
+ switch (operation) {
+ case Qt::NoClip:
+ popClip();
+ break;
+ case Qt::ReplaceClip:
+ clipPath = path;
+ pushClip();
+ break;
+ case Qt::IntersectClip:
+ clipPath &= path;
+ pushClip();
+ break;
+ }
+ }
+
+ void updateClipRegion(const QRegion &region, Qt::ClipOperation operation)
+ {
+ QPainterPath p;
+ p.addRegion(region);
+ updateClipPath(p, operation);
+ }
+
+ void updateBrush(const QBrush &newBrush)
+ {
+ brush.brush = to_d2d_brush(newBrush);
+ if (brush.brush) {
+ brush.brush->SetOpacity(opacity);
+ applyBrushOrigin(currentBrushOrigin);
+ }
+ }
+
+ void updateBrushOrigin(const QPointF &origin)
+ {
+ negateCurrentBrushOrigin();
+ applyBrushOrigin(origin);
+ }
+
+ void negateCurrentBrushOrigin()
+ {
+ if (brush.brush && !currentBrushOrigin.isNull()) {
+ D2D1_MATRIX_3X2_F transform;
+ brush.brush->GetTransform(&transform);
+
+ brush.brush->SetTransform(*(D2D1::Matrix3x2F::ReinterpretBaseType(&transform))
+ * D2D1::Matrix3x2F::Translation(-currentBrushOrigin.x(),
+ -currentBrushOrigin.y()));
+ }
+ }
+
+ void applyBrushOrigin(const QPointF &origin)
+ {
+ if (brush.brush && !origin.isNull()) {
+ D2D1_MATRIX_3X2_F transform;
+ brush.brush->GetTransform(&transform);
+
+ brush.brush->SetTransform(*(D2D1::Matrix3x2F::ReinterpretBaseType(&transform))
+ * D2D1::Matrix3x2F::Translation(origin.x(), origin.y()));
+ }
+
+ currentBrushOrigin = origin;
+ }
+
+ void updatePen(const QPen &newPen)
+ {
+ pen.reset();
+
+ if (newPen.style() == Qt::NoPen)
+ return;
+
+ pen.isNull = false;
+ pen.brush = to_d2d_brush(newPen.brush());
+ if (!pen.brush)
+ return;
+
+ pen.width = newPen.widthF();
+ pen.color = newPen.color();
+ pen.brush->SetOpacity(opacity);
+
+ D2D1_STROKE_STYLE_PROPERTIES1 props = {};
+
+ // Try and match Qt's raster engine in output as closely as possible
+ switch (newPen.style()) {
+ case Qt::DotLine:
+ case Qt::DashDotLine:
+ case Qt::DashDotDotLine:
+ if (pen.width <= 1.0) {
+ props.startCap = props.endCap = props.dashCap = D2D1_CAP_STYLE_FLAT;
+ break;
+ }
+ // fall through
+ default:
+ switch (newPen.capStyle()) {
+ case Qt::SquareCap:
+ props.startCap = props.endCap = props.dashCap = D2D1_CAP_STYLE_SQUARE;
+ break;
+ case Qt::RoundCap:
+ props.startCap = props.endCap = props.dashCap = D2D1_CAP_STYLE_ROUND;
+ case Qt::FlatCap:
+ default:
+ props.startCap = props.endCap = props.dashCap = D2D1_CAP_STYLE_FLAT;
+ break;
+ }
+ break;
+ }
+
+ switch (newPen.joinStyle()) {
+ case Qt::BevelJoin:
+ props.lineJoin = D2D1_LINE_JOIN_BEVEL;
+ break;
+ case Qt::RoundJoin:
+ props.lineJoin = D2D1_LINE_JOIN_ROUND;
+ break;
+ case Qt::MiterJoin:
+ default:
+ props.lineJoin = D2D1_LINE_JOIN_MITER;
+ break;
+ }
+
+ props.miterLimit = newPen.miterLimit() * qreal(2.0); // D2D and Qt miter specs differ
+ props.dashOffset = newPen.dashOffset();
+ props.transformType = qIsNull(newPen.widthF()) ? D2D1_STROKE_TRANSFORM_TYPE_HAIRLINE
+ : newPen.isCosmetic() ? D2D1_STROKE_TRANSFORM_TYPE_FIXED
+ : D2D1_STROKE_TRANSFORM_TYPE_NORMAL;
+
+ switch (newPen.style()) {
+ case Qt::SolidLine:
+ props.dashStyle = D2D1_DASH_STYLE_SOLID;
+ break;
+ default:
+ props.dashStyle = D2D1_DASH_STYLE_CUSTOM;
+ break;
+ }
+
+ HRESULT hr;
+
+ if (props.dashStyle == D2D1_DASH_STYLE_CUSTOM) {
+ QVector<qreal> dashes = newPen.dashPattern();
+ QVector<FLOAT> converted(dashes.size());
+
+ for (int i = 0; i < dashes.size(); i++) {
+ converted[i] = dashes[i];
+ }
+
+ hr = factory()->CreateStrokeStyle(props, converted.constData(), converted.size(), &(pen.strokeStyle));
+ } else {
+ hr = factory()->CreateStrokeStyle(props, NULL, 0, &(pen.strokeStyle));
+ }
+
+ if (FAILED(hr))
+ qWarning("%s: Could not create stroke style: %#x", __FUNCTION__, hr);
+ }
+
+ ComPtr<ID2D1Brush> to_d2d_brush(const QBrush &newBrush)
+ {
+ HRESULT hr;
+ ComPtr<ID2D1Brush> result;
+
+ switch (newBrush.style()) {
+ case Qt::NoBrush:
+ break;
+
+ case Qt::SolidPattern:
+ {
+ ComPtr<ID2D1SolidColorBrush> solid;
+
+ hr = dc()->CreateSolidColorBrush(to_d2d_color_f(newBrush.color()), &solid);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create solid color brush: %#x", __FUNCTION__, hr);
+ break;
+ }
+
+ hr = solid.As(&result);
+ if (FAILED(hr))
+ qWarning("%s: Could not convert solid color brush: %#x", __FUNCTION__, hr);
+ }
+ break;
+
+ case Qt::Dense1Pattern:
+ case Qt::Dense2Pattern:
+ case Qt::Dense3Pattern:
+ case Qt::Dense4Pattern:
+ case Qt::Dense5Pattern:
+ case Qt::Dense6Pattern:
+ case Qt::Dense7Pattern:
+ case Qt::HorPattern:
+ case Qt::VerPattern:
+ case Qt::CrossPattern:
+ case Qt::BDiagPattern:
+ case Qt::FDiagPattern:
+ case Qt::DiagCrossPattern:
+ {
+ ComPtr<ID2D1BitmapBrush1> bitmapBrush;
+ D2D1_BITMAP_BRUSH_PROPERTIES1 bitmapBrushProperties = {
+ D2D1_EXTEND_MODE_WRAP,
+ D2D1_EXTEND_MODE_WRAP,
+ interpolationMode()
+ };
+
+ QImage brushImg = qt_imageForBrush(newBrush.style(), false);
+ brushImg.setColor(0, newBrush.color().rgba());
+ brushImg.setColor(1, qRgba(0, 0, 0, 0));
+
+ QWindowsDirect2DBitmap bitmap;
+ bool success = bitmap.fromImage(brushImg, Qt::AutoColor);
+ if (!success) {
+ qWarning("%s: Could not create Direct2D bitmap from Qt pattern brush image", __FUNCTION__);
+ break;
+ }
+
+ hr = dc()->CreateBitmapBrush(bitmap.bitmap(),
+ bitmapBrushProperties,
+ &bitmapBrush);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create Direct2D bitmap brush for Qt pattern brush: %#x", __FUNCTION__, hr);
+ break;
+ }
+
+ hr = bitmapBrush.As(&result);
+ if (FAILED(hr))
+ qWarning("%s: Could not convert Direct2D bitmap brush for Qt pattern brush: %#x", __FUNCTION__, hr);
+ }
+ break;
+
+ case Qt::LinearGradientPattern:
+ case Qt::RadialGradientPattern:
+ case Qt::ConicalGradientPattern:
+ break;
+
+ case Qt::TexturePattern:
+ {
+ ComPtr<ID2D1BitmapBrush1> bitmapBrush;
+ D2D1_BITMAP_BRUSH_PROPERTIES1 bitmapBrushProperties = {
+ D2D1_EXTEND_MODE_WRAP,
+ D2D1_EXTEND_MODE_WRAP,
+ interpolationMode()
+ };
+
+ QWindowsDirect2DPlatformPixmap *pp = static_cast<QWindowsDirect2DPlatformPixmap *>(newBrush.texture().handle());
+ QWindowsDirect2DBitmap *bitmap = pp->bitmap();
+ hr = dc()->CreateBitmapBrush(bitmap->bitmap(),
+ bitmapBrushProperties,
+ &bitmapBrush);
+
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create texture brush: %#x", __FUNCTION__, hr);
+ break;
+ }
+
+ hr = bitmapBrush.As(&result);
+ if (FAILED(hr))
+ qWarning("%s: Could not convert texture brush: %#x", __FUNCTION__, hr);
+ }
+ break;
+ }
+
+ if (result && !newBrush.transform().isIdentity())
+ result->SetTransform(to_d2d_matrix_3x2_f(newBrush.transform()));
+
+ return result;
+ }
+
+ void updateHints(QPainter::RenderHints newHints)
+ {
+ renderHints = newHints;
+ dc()->SetAntialiasMode(antialiasMode());
+ }
+
+ template <typename T>
+ void drawLines(const T* lines, int lineCount)
+ {
+ if (!pen.brush)
+ return;
+
+ for (int i = 0; i < lineCount; i++) {
+ const T &line = lines[i];
+
+ // Try to fit Qt's and Direct2D's idea of zero length line
+ // handling together nicely.
+
+ if (line.p1() == line.p2() && pen.strokeStyle.Get()->GetDashCap() != D2D1_CAP_STYLE_SQUARE) {
+ if (pen.width <= 1.0) {
+ dc()->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
+ // Note that we use pointStrokeStyle here, not the pen's stroke style!
+ dc()->DrawLine(to_d2d_point_2f(line.p1()), to_d2d_point_2f(line.p2()), pen.brush.Get(), pen.width, pointStrokeStyle.Get());
+ dc()->SetAntialiasMode(antialiasMode());
+ }
+ } else
+ dc()->DrawLine(to_d2d_point_2f(line.p1()), to_d2d_point_2f(line.p2()), pen.brush.Get(), pen.width, pen.strokeStyle.Get());
+ }
+ }
+
+ template <typename T>
+ void drawRects(const T* rects, int rectCount)
+ {
+ if (!brush.brush && !pen.brush)
+ return;
+
+ for (int i = 0; i < rectCount; i++) {
+ if (brush.brush)
+ dc()->FillRectangle(to_d2d_rect_f(rects[i]), brush.brush.Get());
+
+ // Direct2D for some reason uses different geometry in FillRectangle and DrawRectangle.
+ // We have to adjust the rect right and down here by one pixel to paint the rectangle properly.
+ if (pen.brush)
+ dc()->DrawRectangle(to_d2d_rect_f(rects[i].adjusted(1, 1, 1, 1)), pen.brush.Get(), pen.width, pen.strokeStyle.Get());
+ }
+ }
+
+ template <typename T>
+ void drawPolygon(const T* points, int pointCount, QPaintEngine::PolygonDrawMode mode)
+ {
+ if (pointCount < 3)
+ return;
+
+ if (!brush.brush && !pen.brush)
+ return;
+
+ QVector<D2D1_POINT_2F> converted(pointCount);
+ for (int i = 0; i < pointCount; i++) {
+ const T &p = points[i];
+ converted[i].x = p.x();
+ converted[i].y = p.y();
+ }
+
+ drawPolygon(converted.constData(), converted.size(), mode);
+ }
+
+ void drawPolygon(const D2D1_POINT_2F *points, int pointCount, QPaintEngine::PolygonDrawMode mode)
+ {
+ ComPtr<ID2D1PathGeometry> geometry;
+ ComPtr<ID2D1GeometrySink> sink;
+ const bool is_polyline = mode == QPaintEngine::PolylineMode;
+
+ HRESULT hr = factory()->CreatePathGeometry(&geometry);
+ if (FAILED(hr))
+ return;
+
+ hr = geometry->Open(&sink);
+ if (FAILED(hr))
+ return;
+
+ switch (mode) {
+ case QPaintEngine::OddEvenMode:
+ sink->SetFillMode(D2D1_FILL_MODE_ALTERNATE);
+ break;
+ case QPaintEngine::WindingMode:
+ sink->SetFillMode(D2D1_FILL_MODE_WINDING);
+ break;
+ case QPaintEngine::ConvexMode:
+ case QPaintEngine::PolylineMode:
+ // XXX
+ break;
+ }
+
+ sink->BeginFigure(points[0], is_polyline ? D2D1_FIGURE_BEGIN_HOLLOW
+ : D2D1_FIGURE_BEGIN_FILLED);
+ sink->AddLines(points + 1, pointCount - 1);
+ sink->EndFigure(is_polyline ? D2D1_FIGURE_END_OPEN
+ : D2D1_FIGURE_END_CLOSED);
+ sink->Close();
+
+ if (brush.brush)
+ dc()->FillGeometry(geometry.Get(), brush.brush.Get());
+
+ if (pen.brush)
+ dc()->DrawGeometry(geometry.Get(), pen.brush.Get(), pen.width, pen.strokeStyle.Get());
+ }
+};
+
+QWindowsDirect2DPaintEngine::QWindowsDirect2DPaintEngine(QWindowsDirect2DBitmap *bitmap)
+ : QPaintEngine(PrimitiveTransform
+ | PatternTransform
+ | PixmapTransform
+ | PatternBrush
+ | AlphaBlend
+ | PainterPaths
+ | Antialiasing
+ | BrushStroke
+ | ConstantOpacity
+ | MaskedBrush
+ | ObjectBoundingModeGradients
+
+ // Although Direct2D 1.1 contains support for both linear and radial gradients,
+ // there unfortunately is no support for repeating or reflecting versions of them
+ //| LinearGradientFill
+ //| RadialGradientFill
+
+ // Unsupported entirely by Direct2D 1.1
+ //| ConicalGradientFill
+
+ // We might be able to support this using Direct2D effects
+ //| PorterDuff
+
+ // Direct2D currently only supports affine transforms directly
+ // We might be able to support this using Direct2D effects
+ //| PerspectiveTransform
+
+ // We might be able to support this using Direct2D effects
+ //| BlendModes
+
+ // We might be able to support this using Direct2D effects
+ //| RasterOpModes
+
+ // We have to inform Direct2D when we start and end drawing
+ //| PaintOutsidePaintEvent
+ )
+ , d_ptr(new QWindowsDirect2DPaintEnginePrivate(bitmap))
+{
+
+}
+
+bool QWindowsDirect2DPaintEngine::begin(QPaintDevice * pdev)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+
+ d->bitmap->deviceContext()->begin();
+ d->dc()->SetTransform(D2D1::Matrix3x2F::Identity());
+
+ QRect clip(0, 0, pdev->width(), pdev->height());
+ if (!systemClip().isEmpty()) {
+ clip &= systemClip().boundingRect();
+ }
+ d->dc()->PushAxisAlignedClip(to_d2d_rect_f(clip), d->antialiasMode());
+ updateState(*state);
+
+ D2D_TAG(D2DDebugDrawInitialStateTag);
+
+ return true;
+}
+
+bool QWindowsDirect2DPaintEngine::end()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->popClip();
+ d->dc()->PopAxisAlignedClip();
+ return d->bitmap->deviceContext()->end();
+}
+
+void QWindowsDirect2DPaintEngine::updateState(const QPaintEngineState &state)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateState(state, state.state());
+}
+
+QPaintEngine::Type QWindowsDirect2DPaintEngine::type() const
+{
+ return QPaintEngine::Direct2D;
+}
+
+void QWindowsDirect2DPaintEngine::drawEllipse(const QRectF &rect)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawEllipseTag);
+
+ D2D1_ELLIPSE ellipse = {
+ to_d2d_point_2f(rect.center()),
+ rect.width() / 2,
+ rect.height() / 2
+ };
+
+ if (d->brush.brush)
+ d->dc()->FillEllipse(ellipse, d->brush.brush.Get());
+
+ if (d->pen.brush) {
+ d->dc()->DrawEllipse(ellipse, d->pen.brush.Get(), d->pen.width, d->pen.strokeStyle.Get());
+ }
+}
+
+void QWindowsDirect2DPaintEngine::drawEllipse(const QRect &rect)
+{
+ drawEllipse(QRectF(rect));
+}
+
+void QWindowsDirect2DPaintEngine::drawImage(const QRectF &rectangle, const QImage &image,
+ const QRectF &sr, Qt::ImageConversionFlags flags)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawImageTag);
+
+ QPixmap pixmap = QPixmap::fromImage(image, flags);
+ drawPixmap(rectangle, pixmap, sr);
+}
+
+void QWindowsDirect2DPaintEngine::drawLines(const QLineF *lines, int lineCount)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawLinesTag);
+ d->drawLines(lines, lineCount);
+}
+
+void QWindowsDirect2DPaintEngine::drawLines(const QLine *lines, int lineCount)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawLinesTag);
+ d->drawLines(lines, lineCount);
+}
+
+void QWindowsDirect2DPaintEngine::drawPath(const QPainterPath &path)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawPathTag);
+
+ if (path.elementCount() == 0)
+ return;
+
+ if (!d->brush.brush && !d->pen.brush)
+ return;
+
+ ComPtr<ID2D1PathGeometry> geometry = painterPathToPathGeometry(path);
+ if (!geometry)
+ return;
+
+ if (d->brush.brush)
+ d->dc()->FillGeometry(geometry.Get(), d->brush.brush.Get());
+
+ if (d->pen.brush)
+ d->dc()->DrawGeometry(geometry.Get(), d->pen.brush.Get(), d->pen.width, d->pen.strokeStyle.Get());
+}
+
+void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
+ const QPixmap &pm,
+ const QRectF &sr)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawPixmapTag);
+
+ if (pm.isNull())
+ return;
+
+ if (pm.handle()->pixelType() == QPlatformPixmap::BitmapType) {
+ QImage i = pm.toImage();
+ i.setColor(0, qRgba(0, 0, 0, 0));
+ i.setColor(1, d->pen.color.rgba());
+ drawImage(r, i, sr);
+ return;
+ }
+
+ QWindowsDirect2DPlatformPixmap *pp = static_cast<QWindowsDirect2DPlatformPixmap *>(pm.handle());
+ QWindowsDirect2DBitmap *bitmap = pp->bitmap();
+
+ if (bitmap->bitmap() != d->bitmap->bitmap()) {
+ // Good, src bitmap != dst bitmap
+ if (sr.isValid())
+ d->dc()->DrawBitmap(bitmap->bitmap(),
+ to_d2d_rect_f(r), d->opacity,
+ d->interpolationMode(),
+ to_d2d_rect_f(sr));
+ else
+ d->dc()->DrawBitmap(bitmap->bitmap(),
+ to_d2d_rect_f(r), d->opacity,
+ d->interpolationMode());
+ } else {
+ // Ok, so the source pixmap and destination pixmap is the same.
+ // D2D is not fond of this scenario, deal with it through
+ // an intermediate bitmap
+ QWindowsDirect2DBitmap intermediate;
+
+ if (sr.isValid()) {
+ bool r = intermediate.resize(sr.width(), sr.height());
+ if (!r) {
+ qDebug("%s: Could not resize intermediate bitmap to source rect size", __FUNCTION__);
+ return;
+ }
+
+ D2D1_RECT_U d2d_sr = to_d2d_rect_u(sr.toRect());
+ HRESULT hr = intermediate.bitmap()->CopyFromBitmap(NULL,
+ bitmap->bitmap(),
+ &d2d_sr);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not copy source rect area from source bitmap to intermediate bitmap: %#x", __FUNCTION__, hr);
+ return;
+ }
+ } else {
+ bool r = intermediate.resize(bitmap->size().width(),
+ bitmap->size().height());
+ if (!r) {
+ qDebug("%s: Could not resize intermediate bitmap to source bitmap size", __FUNCTION__);
+ return;
+ }
+
+ HRESULT hr = intermediate.bitmap()->CopyFromBitmap(NULL,
+ bitmap->bitmap(),
+ NULL);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not copy source bitmap to intermediate bitmap: %#x", __FUNCTION__, hr);
+ return;
+ }
+ }
+
+ d->dc()->DrawBitmap(intermediate.bitmap(),
+ to_d2d_rect_f(r), d->opacity,
+ d->interpolationMode());
+ }
+}
+
+void QWindowsDirect2DPaintEngine::drawPolygon(const QPointF *points,
+ int pointCount,
+ QPaintEngine::PolygonDrawMode mode)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawPolygonTag);
+ d->drawPolygon(points, pointCount, mode);
+}
+
+void QWindowsDirect2DPaintEngine::drawPolygon(const QPoint *points,
+ int pointCount,
+ QPaintEngine::PolygonDrawMode mode)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawPolygonTag);
+ d->drawPolygon(points, pointCount, mode);
+}
+
+void QWindowsDirect2DPaintEngine::drawRects(const QRectF *rects, int rectCount)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawRectsTag);
+ d->drawRects(rects, rectCount);
+}
+
+void QWindowsDirect2DPaintEngine::drawRects(const QRect *rects, int rectCount)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawRectsTag);
+ d->drawRects(rects, rectCount);
+}
+
+// Points (1/72 inches) to Microsoft's Device Independent Pixels (1/96 inches)
+inline static Q_DECL_CONSTEXPR FLOAT pointSizeToDIP(qreal pointSize)
+{
+ return pointSize + (pointSize / qreal(3.0));
+}
+
+inline static FLOAT pixelSizeToDIP(int pixelSize)
+{
+ FLOAT dpiX, dpiY;
+ factory()->GetDesktopDpi(&dpiX, &dpiY);
+
+ return FLOAT(pixelSize) / (dpiY / 96.0f);
+}
+
+inline static FLOAT fontSizeInDIP(const QFont &font)
+{
+ // Microsoft wants the font size in DIPs (Device Independent Pixels), each of which is 1/96 inches.
+ if (font.pixelSize() == -1) {
+ // font size was set as points
+ return pointSizeToDIP(font.pointSizeF());
+ } else {
+ // font size was set as pixels
+ return pixelSizeToDIP(font.pixelSize());
+ }
+}
+
+void QWindowsDirect2DPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawTextItemTag);
+
+ if (d->pen.isNull)
+ return;
+
+ // If we can't support the current configuration with Direct2D, fall back to slow path
+ // Most common cases are perspective transform and gradient brush as pen
+ if (d->hasPerspectiveTransform || !d->pen.brush) {
+ QPaintEngine::drawTextItem(p, textItem);
+ return;
+ }
+
+ const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
+ ComPtr<IDWriteFontFace> fontFace;
+
+ switch (ti.fontEngine->type()) {
+ case QFontEngine::Win:
+ {
+ QWindowsFontEngine *wfe = static_cast<QWindowsFontEngine *>(ti.fontEngine);
+ QSharedPointer<QWindowsFontEngineData> wfed = wfe->fontEngineData();
+
+ HGDIOBJ oldfont = wfe->selectDesignFont();
+ HRESULT hr = QWindowsDirect2DContext::instance()->dwriteGdiInterop()->CreateFontFaceFromHdc(wfed->hdc, &fontFace);
+ DeleteObject(SelectObject(wfed->hdc, oldfont));
+ if (FAILED(hr))
+ qWarning("%s: Could not create DirectWrite fontface from HDC: %#x", __FUNCTION__, hr);
+
+ }
+ break;
+
+#ifndef QT_NO_DIRECTWRITE
+
+ case QFontEngine::DirectWrite:
+ {
+ QWindowsFontEngineDirectWrite *wfedw = static_cast<QWindowsFontEngineDirectWrite *>(ti.fontEngine);
+ fontFace = wfedw->directWriteFontFace();
+ }
+ break;
+
+#endif // QT_NO_DIRECTWRITE
+
+ default:
+ qDebug("%s: Unknown font engine!", __FUNCTION__);
+ break;
+ }
+
+ if (!fontFace) {
+ qDebug("%s: Could not find font - falling back to slow text rendering path.", __FUNCTION__);
+ QPaintEngine::drawTextItem(p, textItem);
+ return;
+ }
+
+ QVector<UINT16> glyphIndices(ti.glyphs.numGlyphs);
+ QVector<FLOAT> glyphAdvances(ti.glyphs.numGlyphs);
+ QVector<DWRITE_GLYPH_OFFSET> glyphOffsets(ti.glyphs.numGlyphs);
+
+ // Imperfect conversion here
+ for (int i = 0; i < ti.glyphs.numGlyphs; i++) {
+ glyphIndices[i] = UINT16(ti.glyphs.glyphs[i]);
+ glyphAdvances[i] = ti.glyphs.effectiveAdvance(i).toReal();
+ glyphOffsets[i].advanceOffset = ti.glyphs.offsets[i].x.toReal();
+ glyphOffsets[i].ascenderOffset = ti.glyphs.offsets[i].y.toReal();
+ }
+
+ const bool rtl = (ti.flags & QTextItem::RightToLeft);
+ const UINT32 bidiLevel = rtl ? 1 : 0;
+
+ DWRITE_GLYPH_RUN glyphRun = {
+ fontFace.Get(), // IDWriteFontFace *fontFace;
+ fontSizeInDIP(ti.font()), // FLOAT fontEmSize;
+ ti.glyphs.numGlyphs, // UINT32 glyphCount;
+ glyphIndices.constData(), // const UINT16 *glyphIndices;
+ glyphAdvances.constData(), // const FLOAT *glyphAdvances;
+ glyphOffsets.constData(), // const DWRITE_GLYPH_OFFSET *glyphOffsets;
+ FALSE, // BOOL isSideways;
+ bidiLevel // UINT32 bidiLevel;
+ };
+
+ const bool antiAlias = bool((d->renderHints & QPainter::TextAntialiasing)
+ && !(ti.font().styleStrategy() & QFont::NoAntialias));
+ d->dc()->SetTextAntialiasMode(antiAlias ? D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE
+ : D2D1_TEXT_ANTIALIAS_MODE_ALIASED);
+
+ const QPointF offset(rtl ? ti.width.toReal() : 0, 0);
+ d->dc()->DrawGlyphRun(to_d2d_point_2f(p + offset),
+ &glyphRun,
+ NULL,
+ d->pen.brush.Get(),
+ DWRITE_MEASURING_MODE_GDI_CLASSIC);
+}
+
+static void qt_draw_tile(QPaintEngine *gc, qreal x, qreal y, qreal w, qreal h,
+ const QPixmap &pixmap, qreal xOffset, qreal yOffset)
+{
+ qreal yPos, xPos, drawH, drawW, yOff, xOff;
+ yPos = y;
+ yOff = yOffset;
+ while (yPos < y + h) {
+ drawH = pixmap.height() - yOff; // Cropping first row
+ if (yPos + drawH > y + h) // Cropping last row
+ drawH = y + h - yPos;
+ xPos = x;
+ xOff = xOffset;
+ while (xPos < x + w) {
+ drawW = pixmap.width() - xOff; // Cropping first column
+ if (xPos + drawW > x + w) // Cropping last column
+ drawW = x + w - xPos;
+ if (drawW > 0 && drawH > 0)
+ gc->drawPixmap(QRectF(xPos, yPos, drawW, drawH), pixmap, QRectF(xOff, yOff, drawW, drawH));
+ xPos += drawW;
+ xOff = 0;
+ }
+ yPos += drawH;
+ yOff = 0;
+ }
+}
+
+void QWindowsDirect2DPaintEngine::drawTiledPixmap(const QRectF &rect, const QPixmap &pixmap, const QPointF &p)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawTextItemTag);
+ qt_draw_tile(this, rect.x(), rect.y(), rect.width(), rect.height(), pixmap, p.x(), p.y());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
new file mode 100644
index 0000000000..554380cb1f
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DPAINTENGINE_H
+#define QWINDOWSDIRECT2DPAINTENGINE_H
+
+#include <QtCore/QScopedPointer>
+#include <QtGui/QPaintEngine>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DPaintEnginePrivate;
+class QWindowsDirect2DBitmap;
+
+class QWindowsDirect2DPaintEngine : public QPaintEngine
+{
+ Q_DECLARE_PRIVATE(QWindowsDirect2DPaintEngine)
+
+public:
+ QWindowsDirect2DPaintEngine(QWindowsDirect2DBitmap *bitmap);
+
+ bool begin(QPaintDevice *pdev) Q_DECL_OVERRIDE;
+ bool end() Q_DECL_OVERRIDE;
+
+ void updateState(const QPaintEngineState &state) Q_DECL_OVERRIDE;
+
+ Type type() const Q_DECL_OVERRIDE;
+
+ void drawEllipse(const QRectF &rect) Q_DECL_OVERRIDE;
+ void drawEllipse(const QRect &rect) Q_DECL_OVERRIDE;
+ void drawImage(const QRectF &rectangle, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE;
+ void drawLines(const QLineF *lines, int lineCount) Q_DECL_OVERRIDE;
+ void drawLines(const QLine *lines, int lineCount) Q_DECL_OVERRIDE;
+ void drawPath(const QPainterPath &path) Q_DECL_OVERRIDE;
+ void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) Q_DECL_OVERRIDE;
+ void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) Q_DECL_OVERRIDE;
+ void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) Q_DECL_OVERRIDE;
+ void drawRects(const QRectF *rects, int rectCount) Q_DECL_OVERRIDE;
+ void drawRects(const QRect *rects, int rectCount) Q_DECL_OVERRIDE;
+ void drawTextItem(const QPointF &p, const QTextItem &textItem) Q_DECL_OVERRIDE;
+ void drawTiledPixmap(const QRectF &rect, const QPixmap &pixmap, const QPointF &p) Q_DECL_OVERRIDE;
+
+private:
+ QScopedPointer<QWindowsDirect2DPaintEnginePrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DPAINTENGINE_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
new file mode 100644
index 0000000000..072c4b3c0e
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dpaintdevice.h"
+#include "qwindowsdirect2dplatformpixmap.h"
+#include "qwindowsdirect2dbitmap.h"
+#include "qwindowsdirect2dhelpers.h"
+
+#include <QtGui/QPainter>
+#include <QtGui/QImage>
+#include <QtGui/QPaintDevice>
+#include <QtGui/QPaintEngine>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DPlatformPixmapPrivate
+{
+public:
+ QWindowsDirect2DPlatformPixmapPrivate()
+ : bitmap(new QWindowsDirect2DBitmap)
+ , device(new QWindowsDirect2DPaintDevice(bitmap.data(), QInternal::Pixmap))
+ , devicePixelRatio(1.0)
+ {}
+
+ QScopedPointer<QWindowsDirect2DBitmap> bitmap;
+ QScopedPointer<QWindowsDirect2DPaintDevice> device;
+ qreal devicePixelRatio;
+};
+
+static int qt_d2dpixmap_serno = 0;
+
+QWindowsDirect2DPlatformPixmap::QWindowsDirect2DPlatformPixmap(PixelType pixelType)
+ : QPlatformPixmap(pixelType, Direct2DClass)
+ , d_ptr(new QWindowsDirect2DPlatformPixmapPrivate)
+{
+ setSerialNumber(qt_d2dpixmap_serno++);
+}
+
+QWindowsDirect2DPlatformPixmap::~QWindowsDirect2DPlatformPixmap()
+{
+
+}
+
+void QWindowsDirect2DPlatformPixmap::resize(int width, int height)
+{
+ Q_D(QWindowsDirect2DPlatformPixmap);
+
+ if (!d->bitmap->resize(width, height)) {
+ qWarning("%s: Could not resize bitmap", __FUNCTION__);
+ return;
+ }
+
+ is_null = false;
+ w = width;
+ h = height;
+ this->d = 32;
+}
+
+void QWindowsDirect2DPlatformPixmap::fromImage(const QImage &image,
+ Qt::ImageConversionFlags flags)
+{
+ Q_D(QWindowsDirect2DPlatformPixmap);
+
+ if (!d->bitmap->fromImage(image, flags)) {
+ qWarning("%s: Could not init from image", __FUNCTION__);
+ return;
+ }
+
+ is_null = false;
+ w = image.width();
+ h = image.height();
+ this->d = 32;
+}
+
+int QWindowsDirect2DPlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) const
+{
+ Q_D(const QWindowsDirect2DPlatformPixmap);
+
+ Q_GUI_EXPORT int qt_paint_device_metric(const QPaintDevice *device, QPaintDevice::PaintDeviceMetric metric);
+ return qt_paint_device_metric(d->device.data(), metric);
+}
+
+void QWindowsDirect2DPlatformPixmap::fill(const QColor &color)
+{
+ Q_D(QWindowsDirect2DPlatformPixmap);
+ d->bitmap->fill(color);
+}
+
+bool QWindowsDirect2DPlatformPixmap::hasAlphaChannel() const
+{
+ return true;
+}
+
+QImage QWindowsDirect2DPlatformPixmap::toImage() const
+{
+ return toImage(QRect());
+}
+
+QImage QWindowsDirect2DPlatformPixmap::toImage(const QRect &rect) const
+{
+ Q_D(const QWindowsDirect2DPlatformPixmap);
+
+ bool active = d->device->paintEngine()->isActive();
+
+ if (active)
+ d->device->paintEngine()->end();
+
+ QImage result = d->bitmap->toImage(rect);
+
+ if (active)
+ d->device->paintEngine()->begin(d->device.data());
+
+ return result;
+}
+
+QPaintEngine* QWindowsDirect2DPlatformPixmap::paintEngine() const
+{
+ Q_D(const QWindowsDirect2DPlatformPixmap);
+ return d->device->paintEngine();
+}
+
+qreal QWindowsDirect2DPlatformPixmap::devicePixelRatio() const
+{
+ Q_D(const QWindowsDirect2DPlatformPixmap);
+ return d->devicePixelRatio;
+}
+
+void QWindowsDirect2DPlatformPixmap::setDevicePixelRatio(qreal scaleFactor)
+{
+ Q_D(QWindowsDirect2DPlatformPixmap);
+ d->devicePixelRatio = scaleFactor;
+}
+
+QWindowsDirect2DBitmap *QWindowsDirect2DPlatformPixmap::bitmap() const
+{
+ Q_D(const QWindowsDirect2DPlatformPixmap);
+ return d->bitmap.data();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h
new file mode 100644
index 0000000000..e6684ea423
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DPLATFORMPIXMAP_H
+#define QWINDOWSDIRECT2DPLATFORMPIXMAP_H
+
+#include <QtGui/qpa/qplatformpixmap.h>
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DPlatformPixmapPrivate;
+class QWindowsDirect2DBitmap;
+
+class QWindowsDirect2DPlatformPixmap : public QPlatformPixmap
+{
+ Q_DECLARE_PRIVATE(QWindowsDirect2DPlatformPixmap)
+public:
+ QWindowsDirect2DPlatformPixmap(PixelType pixelType);
+ ~QWindowsDirect2DPlatformPixmap();
+
+ virtual void resize(int width, int height);
+ virtual void fromImage(const QImage &image,
+ Qt::ImageConversionFlags flags);
+
+ virtual int metric(QPaintDevice::PaintDeviceMetric metric) const;
+ virtual void fill(const QColor &color);
+
+ virtual bool hasAlphaChannel() const;
+
+ virtual QImage toImage() const;
+ virtual QImage toImage(const QRect &rect) const;
+
+ virtual QPaintEngine* paintEngine() const;
+
+ virtual qreal devicePixelRatio() const;
+ virtual void setDevicePixelRatio(qreal scaleFactor);
+
+ QWindowsDirect2DBitmap *bitmap() const;
+
+private:
+ QScopedPointer<QWindowsDirect2DPlatformPixmapPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DPLATFORMPIXMAP_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp
new file mode 100644
index 0000000000..f75bb49fd9
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dintegration.h"
+
+#include <QtGui/qpa/qplatformintegrationplugin.h>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "direct2d.json")
+public:
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QPlatformIntegration *QWindowsDirect2DIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ if (system.compare(system, QStringLiteral("direct2d"), Qt::CaseInsensitive) == 0)
+ return QWindowsDirect2DIntegration::create(paramList);
+ return 0;
+}
+
+QT_END_NAMESPACE
+
+#include "qwindowsdirect2dplatformplugin.moc"
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index 4a7c3b279f..584efa1665 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -18,6 +18,10 @@ mac {
win32:!winrt: SUBDIRS += windows
winrt: SUBDIRS += winrt
+contains(QT_CONFIG, direct2d) {
+ SUBDIRS += direct2d
+}
+
qnx {
SUBDIRS += qnx
}