summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/winrt
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2014-03-24 16:10:15 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-03-24 16:10:15 +0100
commit3b5c0bc0780f1749fed7c07bd8b691400a0282b7 (patch)
tree1022f5553ad5a0aca9b5f3b49ca38a01c2329d20 /src/plugins/platforms/winrt
parentc79918733a194ebbe5a2fe1617c884659f3e4b9f (diff)
parent21f1738a94fc8544ece04b3b1ee03a11986fe59b (diff)
Merge remote-tracking branch 'origin/stable' into dev
Conflicts: src/gui/image/qjpeghandler.cpp Change-Id: I9db3acea7d5c82f5da679c8eaeb29431136665f0
Diffstat (limited to 'src/plugins/platforms/winrt')
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.cpp32
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.h2
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.cpp314
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.h19
-rw-r--r--src/plugins/platforms/winrt/qwinrtservices.cpp3
-rw-r--r--src/plugins/platforms/winrt/winrt.pro5
6 files changed, 367 insertions, 8 deletions
diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
index 10136dbead..9b623048af 100644
--- a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
+++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
@@ -207,14 +207,24 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window)
, m_fbo(0)
, m_texture(0)
, m_screen(static_cast<QWinRTScreen*>(window->screen()->handle()))
+ , m_initialized(false)
{
window->setSurfaceType(QSurface::OpenGLSurface); // Required for flipping, but could be done in the swap
+}
- m_context->setFormat(window->requestedFormat());
- m_context->setScreen(window->screen());
- m_context->create();
+bool QWinRTBackingStore::initialize()
+{
+ if (m_initialized)
+ return true;
+
+ m_context->setFormat(window()->requestedFormat());
+ m_context->setScreen(window()->screen());
+ if (!m_context->create())
+ return false;
+
+ if (!m_context->makeCurrent(window()))
+ return false;
- m_context->makeCurrent(window);
glGenFramebuffers(1, &m_fbo);
glGenRenderbuffers(1, &m_rbo);
glGenTextures(1, &m_texture);
@@ -258,11 +268,14 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window)
glProgramBinaryOES(m_shaderProgram, GL_PROGRAM_BINARY_ANGLE, binary.constData(), binary.size());
#endif
m_context->doneCurrent();
- resize(window->size(), QRegion());
+ m_initialized = true;
+ return true;
}
QWinRTBackingStore::~QWinRTBackingStore()
{
+ if (!m_initialized)
+ return;
glDeleteBuffers(1, &m_fbo);
glDeleteRenderbuffers(1, &m_rbo);
glDeleteTextures(1, &m_texture);
@@ -277,6 +290,8 @@ QPaintDevice *QWinRTBackingStore::paintDevice()
void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
Q_UNUSED(offset)
+ if (m_size.isEmpty())
+ return;
const QImage *image = static_cast<QImage *>(m_paintDevice.data());
@@ -334,10 +349,16 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPo
void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents)
{
Q_UNUSED(staticContents)
+ if (!initialize())
+ return;
+
if (m_size == size)
return;
m_size = size;
+ if (m_size.isEmpty())
+ return;
+
m_paintDevice.reset(new QImage(m_size, QImage::Format_ARGB32_Premultiplied));
m_context->makeCurrent(window());
@@ -360,6 +381,7 @@ void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents
void QWinRTBackingStore::beginPaint(const QRegion &region)
{
Q_UNUSED(region)
+ resize(window()->size(), QRegion());
}
void QWinRTBackingStore::endPaint()
diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.h b/src/plugins/platforms/winrt/qwinrtbackingstore.h
index 8be549b441..726f7c838f 100644
--- a/src/plugins/platforms/winrt/qwinrtbackingstore.h
+++ b/src/plugins/platforms/winrt/qwinrtbackingstore.h
@@ -62,6 +62,8 @@ public:
void resize(const QSize &size, const QRegion &staticContents);
private:
+ bool initialize();
+ bool m_initialized;
QSize m_size;
QScopedPointer<QPaintDevice> m_paintDevice;
QScopedPointer<QOpenGLContext> m_context;
diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
index c7fa339fad..3da87de708 100644
--- a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
@@ -44,6 +44,14 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QFile>
+#ifndef Q_OS_WINPHONE
+#include <QtCore/QUuid>
+#include <QtGui/private/qfontengine_ft_p.h>
+#include <dwrite_1.h>
+#include <wrl.h>
+using namespace Microsoft::WRL;
+#endif // !Q_OS_WINPHONE
+
QT_BEGIN_NAMESPACE
QString QWinRTFontDatabase::fontDir() const
@@ -54,11 +62,315 @@ QString QWinRTFontDatabase::fontDir() const
const QString applicationDirPath = QCoreApplication::applicationDirPath();
fontDirectory = applicationDirPath + QLatin1String("/fonts");
if (!QFile::exists(fontDirectory)) {
- qWarning("No fonts directory found in application package.");
+#ifndef Q_OS_WINPHONE
+ if (m_fonts.isEmpty())
+#endif
+ qWarning("No fonts directory found in application package.");
fontDirectory = applicationDirPath;
}
}
return fontDirectory;
}
+#ifndef Q_OS_WINPHONE
+
+QWinRTFontDatabase::~QWinRTFontDatabase()
+{
+ foreach (IDWriteFontFile *fontFile, m_fonts.keys())
+ fontFile->Release();
+}
+
+QFont QWinRTFontDatabase::defaultFont() const
+{
+ return QFont(QStringLiteral("Segoe UI"));
+}
+
+void QWinRTFontDatabase::populateFontDatabase()
+{
+ ComPtr<IDWriteFactory1> factory;
+ HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, __uuidof(IDWriteFactory1), &factory);
+ if (FAILED(hr)) {
+ qWarning("Failed to create DirectWrite factory: %s", qPrintable(qt_error_string(hr)));
+ QBasicFontDatabase::populateFontDatabase();
+ return;
+ }
+
+ ComPtr<IDWriteFontCollection> fontCollection;
+ hr = factory->GetSystemFontCollection(&fontCollection);
+ if (FAILED(hr)) {
+ qWarning("Failed to open system font collection: %s", qPrintable(qt_error_string(hr)));
+ QBasicFontDatabase::populateFontDatabase();
+ return;
+ }
+
+ int fontFamilyCount = fontCollection->GetFontFamilyCount();
+ for (int i = 0; i < fontFamilyCount; ++i) {
+ ComPtr<IDWriteFontFamily> fontFamily;
+ hr = fontCollection->GetFontFamily(i, &fontFamily);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font family: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+
+ ComPtr<IDWriteLocalizedStrings> names;
+ hr = fontFamily->GetFamilyNames(&names);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font family names: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ quint32 familyNameLength;
+ hr = names->GetStringLength(0, &familyNameLength);
+ if (FAILED(hr)) {
+ qWarning("Unable to get family name length: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ QVector<wchar_t> familyBuffer(familyNameLength + 1);
+ hr = names->GetString(0, familyBuffer.data(), familyBuffer.size());
+ if (FAILED(hr)) {
+ qWarning("Unable to create font family name: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ QString familyName = QString::fromWCharArray(familyBuffer.data(), familyNameLength);
+
+ int fontCount = fontFamily->GetFontCount();
+ for (int j = 0; j < fontCount; ++j) {
+ ComPtr<IDWriteFont> font;
+ hr = fontFamily->GetFont(j, &font);
+ if (FAILED(hr)) {
+ qWarning("Unable to get base font: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+
+ ComPtr<IDWriteFontFace> baseFontFace;
+ hr = font->CreateFontFace(&baseFontFace);
+ if (FAILED(hr)) {
+ qWarning("Unable to create base font face: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ ComPtr<IDWriteFontFace1> fontFace;
+ hr = baseFontFace.As(&fontFace);
+ if (FAILED(hr)) {
+ qWarning("Unable to create font face: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+
+ // Only try to load true-type fonts
+ DWRITE_FONT_FACE_TYPE type = fontFace->GetType();
+ if (!(type == DWRITE_FONT_FACE_TYPE_TRUETYPE
+ || type == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION)) {
+ continue;
+ }
+
+ // We can't deal with multi-file fonts
+ quint32 fileCount;
+ hr = fontFace->GetFiles(&fileCount, NULL);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file count: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ if (fileCount != 1) // Should not happen as we only look at TT fonts
+ continue;
+
+ ComPtr<IDWriteLocalizedStrings> informationalStrings;
+ BOOL exists;
+ hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_MANUFACTURER,
+ &informationalStrings, &exists);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font foundry: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ QString foundryName;
+ if (exists) {
+ quint32 length;
+ hr = informationalStrings->GetStringLength(0, &length);
+ if (FAILED(hr))
+ qWarning("Unable to get foundry name length: %s", qPrintable(qt_error_string(hr)));
+ if (SUCCEEDED(hr)) {
+ QVector<wchar_t> buffer(length + 1);
+ hr = informationalStrings->GetString(0, buffer.data(), buffer.size());
+ if (FAILED(hr))
+ qWarning("Unable to get foundry name: %s", qPrintable(qt_error_string(hr)));
+ if (SUCCEEDED(hr))
+ foundryName = QString::fromWCharArray(buffer.data(), length);
+ }
+ }
+
+ QFont::Weight weight;
+ switch (font->GetWeight()) {
+ case DWRITE_FONT_WEIGHT_THIN:
+ case DWRITE_FONT_WEIGHT_EXTRA_LIGHT:
+ case DWRITE_FONT_WEIGHT_LIGHT:
+ case DWRITE_FONT_WEIGHT_SEMI_LIGHT:
+ weight = QFont::Light;
+ break;
+ default:
+ case DWRITE_FONT_WEIGHT_NORMAL:
+ case DWRITE_FONT_WEIGHT_MEDIUM:
+ weight = QFont::Normal;
+ break;
+ case DWRITE_FONT_WEIGHT_DEMI_BOLD:
+ weight = QFont::DemiBold;
+ break;
+ case DWRITE_FONT_WEIGHT_BOLD:
+ case DWRITE_FONT_WEIGHT_EXTRA_BOLD:
+ weight = QFont::Bold;
+ break;
+ case DWRITE_FONT_WEIGHT_BLACK:
+ case DWRITE_FONT_WEIGHT_EXTRA_BLACK:
+ weight = QFont::Black;
+ break;
+ }
+
+ QFont::Style style;
+ switch (font->GetStyle()) {
+ default:
+ case DWRITE_FONT_STYLE_NORMAL:
+ style = QFont::StyleNormal;
+ break;
+ case DWRITE_FONT_STYLE_OBLIQUE:
+ style = QFont::StyleOblique;
+ break;
+ case DWRITE_FONT_STYLE_ITALIC:
+ style = QFont::StyleItalic;
+ break;
+ }
+
+ QFont::Stretch stretch;
+ switch (font->GetStretch()) {
+ default:
+ case DWRITE_FONT_STRETCH_UNDEFINED:
+ case DWRITE_FONT_STRETCH_NORMAL:
+ stretch = QFont::Unstretched;
+ break;
+ case DWRITE_FONT_STRETCH_ULTRA_CONDENSED:
+ stretch = QFont::UltraCondensed;
+ break;
+ case DWRITE_FONT_STRETCH_EXTRA_CONDENSED:
+ stretch = QFont::ExtraCondensed;
+ break;
+ case DWRITE_FONT_STRETCH_CONDENSED:
+ stretch = QFont::Condensed;
+ break;
+ case DWRITE_FONT_STRETCH_SEMI_CONDENSED:
+ stretch = QFont::SemiCondensed;
+ break;
+ case DWRITE_FONT_STRETCH_SEMI_EXPANDED:
+ stretch = QFont::SemiExpanded;
+ break;
+ case DWRITE_FONT_STRETCH_EXPANDED:
+ stretch = QFont::Expanded;
+ break;
+ case DWRITE_FONT_STRETCH_EXTRA_EXPANDED:
+ stretch = QFont::ExtraExpanded;
+ break;
+ case DWRITE_FONT_STRETCH_ULTRA_EXPANDED:
+ stretch = QFont::UltraExpanded;
+ break;
+ }
+
+ const bool fixedPitch = fontFace->IsMonospacedFont();
+
+ quint32 unicodeRange[4];
+ quint32 actualRangeCount;
+ hr = fontFace->GetUnicodeRanges(
+ 2, reinterpret_cast<DWRITE_UNICODE_RANGE *>(unicodeRange), &actualRangeCount);
+ if (FAILED(hr) && hr != E_NOT_SUFFICIENT_BUFFER) { // Ignore insufficient buffer; we only need 4 indices
+ qWarning("Unable to get font unicode range: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ quint32 codePageRange[2] = { 0, 0 };
+ QSupportedWritingSystems writingSystems =
+ QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
+
+ IDWriteFontFile *fontFile;
+ hr = fontFace->GetFiles(&fileCount, &fontFile);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+
+ FontDescription description = { fontFace->GetIndex(), QUuid::createUuid().toByteArray() };
+ m_fonts.insert(fontFile, description);
+ registerFont(familyName, QString(), foundryName, weight, style, stretch,
+ true, true, 0, fixedPitch, writingSystems, fontFile);
+ }
+ }
+
+ QBasicFontDatabase::populateFontDatabase();
+}
+
+QFontEngine *QWinRTFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
+{
+ IDWriteFontFile *fontFile = reinterpret_cast<IDWriteFontFile *>(handle);
+ if (!m_fonts.contains(fontFile))
+ return QBasicFontDatabase::fontEngine(fontDef, handle);
+
+ const void *referenceKey;
+ quint32 referenceKeySize;
+ HRESULT hr = fontFile->GetReferenceKey(&referenceKey, &referenceKeySize);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file reference key: %s", qPrintable(qt_error_string(hr)));
+ return 0;
+ }
+
+ ComPtr<IDWriteFontFileLoader> loader;
+ hr = fontFile->GetLoader(&loader);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file loader: %s", qPrintable(qt_error_string(hr)));
+ return 0;
+ }
+
+ ComPtr<IDWriteFontFileStream> stream;
+ hr =loader->CreateStreamFromKey(referenceKey, referenceKeySize, &stream);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file stream: %s", qPrintable(qt_error_string(hr)));
+ return 0;
+ }
+
+ quint64 fileSize;
+ hr = stream->GetFileSize(&fileSize);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file size: %s", qPrintable(qt_error_string(hr)));
+ return 0;
+ }
+
+ const void *data;
+ void *context;
+ hr = stream->ReadFileFragment(&data, 0, fileSize, &context);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file data: %s", qPrintable(qt_error_string(hr)));
+ return 0;
+ }
+ const QByteArray fontData((const char *)data, fileSize);
+ stream->ReleaseFileFragment(context);
+
+ QFontEngine::FaceId faceId;
+ const FontDescription description = m_fonts.value(fontFile);
+ faceId.uuid = description.uuid;
+ faceId.index = description.index;
+ const bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
+ QFontEngineFT::GlyphFormat format = antialias ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
+ QFontEngineFT *engine = new QFontEngineFT(fontDef);
+ if (!engine->init(faceId, antialias, format, fontData) || engine->invalid()) {
+ delete engine;
+ return 0;
+ }
+
+ return engine;
+}
+
+void QWinRTFontDatabase::releaseHandle(void *handle)
+{
+ IDWriteFontFile *fontFile = reinterpret_cast<IDWriteFontFile *>(handle);
+ if (m_fonts.contains(fontFile)) {
+ m_fonts.remove(fontFile);
+ fontFile->Release();
+ return;
+ }
+
+ QBasicFontDatabase::releaseHandle(handle);
+}
+
+#endif // !Q_OS_WINPHONE
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.h b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
index 49e32470c2..6f194a10cc 100644
--- a/src/plugins/platforms/winrt/qwinrtfontdatabase.h
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
@@ -46,10 +46,29 @@
QT_BEGIN_NAMESPACE
+#ifndef Q_OS_WINPHONE
+struct IDWriteFontFile;
+
+struct FontDescription
+{
+ quint32 index;
+ QByteArray uuid;
+};
+#endif
+
class QWinRTFontDatabase : public QBasicFontDatabase
{
public:
QString fontDir() const;
+#ifndef Q_OS_WINPHONE
+ ~QWinRTFontDatabase();
+ QFont defaultFont() const Q_DECL_OVERRIDE;
+ void populateFontDatabase() Q_DECL_OVERRIDE;
+ QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) Q_DECL_OVERRIDE;
+ void releaseHandle(void *handle) Q_DECL_OVERRIDE;
+private:
+ QHash<IDWriteFontFile *, FontDescription> m_fonts;
+#endif // !Q_OS_WINPHONE
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtservices.cpp b/src/plugins/platforms/winrt/qwinrtservices.cpp
index 8f0a1d55bb..73c090351b 100644
--- a/src/plugins/platforms/winrt/qwinrtservices.cpp
+++ b/src/plugins/platforms/winrt/qwinrtservices.cpp
@@ -106,8 +106,7 @@ bool QWinRTServices::openDocument(const QUrl &url)
if (!(m_fileFactory && m_launcher))
return QPlatformServices::openDocument(url);
- QString pathString = QDir::toNativeSeparators(
- QDir::cleanPath(qApp->applicationDirPath().append(url.toString(QUrl::RemoveScheme))));
+ const QString pathString = QDir::toNativeSeparators(url.toLocalFile());
HSTRING_HEADER header; HSTRING path;
WindowsCreateStringReference((const wchar_t*)pathString.utf16(), pathString.length(), &header, &path);
IAsyncOperation<StorageFile*> *fileOp;
diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro
index 6e3cfb1d20..306bbc8174 100644
--- a/src/plugins/platforms/winrt/winrt.pro
+++ b/src/plugins/platforms/winrt/winrt.pro
@@ -11,6 +11,11 @@ DEFINES *= QT_NO_CAST_FROM_ASCII __WRL_NO_DEFAULT_LIB__ GL_GLEXT_PROTOTYPES
LIBS += $$QMAKE_LIBS_CORE
+!winphone {
+ LIBS += -ldwrite
+ INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/freetype/include
+}
+
SOURCES = \
main.cpp \
qwinrtbackingstore.cpp \