diff options
Diffstat (limited to 'src/plugins')
31 files changed, 511 insertions, 169 deletions
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index b987c49c9c..a38741cc91 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -50,7 +50,7 @@ #include "qdebug.h" -static const char m_qtTag[] = "QtA11y"; +static const char m_qtTag[] = "Qt A11Y"; static const char m_classErrorMsg[] = "Can't find class \"%s\""; static const char m_methodErrorMsg[] = "Can't find method \"%s%s\""; @@ -184,8 +184,6 @@ if (!clazz) { \ desc = iface->text(QAccessible::Name); if (desc.isEmpty()) desc = iface->text(QAccessible::Description); - - desc += QChar(' ') + QString::fromUtf8(qAccessibleRoleString(iface->role())); } jstring jdesc = env->NewString((jchar*) desc.constData(), (jsize) desc.size()); @@ -216,12 +214,6 @@ if (!clazz) { \ } } - if ((iface->role() != QAccessible::NoRole) && - (iface->role() != QAccessible::Client) && - (iface->role() != QAccessible::Pane)) { - desc += QChar(' ') + QString::fromUtf8(qAccessibleRoleString(iface->role())); - } - CALL_METHOD(node, "setEnabled", "(Z)V", !state.disabled) //CALL_METHOD(node, "setFocusable", "(Z)V", state.focusable) CALL_METHOD(node, "setFocusable", "(Z)V", true) diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index ff1a40bfc5..2998762cc3 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -769,7 +769,6 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/) || !QtAndroidInput::registerNatives(env) || !QtAndroidClipboard::registerNatives(env) || !QtAndroidMenu::registerNatives(env) - || !QtAndroidAccessibility::registerNatives(env) || !QtAndroidDialogHelpers::registerNatives(env)) { __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed"); return -1; diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index e255a49ac7..c2e5f83639 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -591,19 +591,37 @@ jboolean QAndroidInputContext::endBatchEdit() return JNI_TRUE; } -jboolean QAndroidInputContext::commitText(const QString &text, jint /*newCursorPosition*/) +/* + Android docs say: If composing, replace compose text with \a text. + Otherwise insert \a text at current cursor position. + + The cursor should then be moved to newCursorPosition. If > 0, this is + relative to the end of the text - 1; if <= 0, this is relative to the start + of the text. updateSelection() needs to be called. +*/ +jboolean QAndroidInputContext::commitText(const QString &text, jint newCursorPosition) { - QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery(); - if (query.isNull()) - return JNI_FALSE; + QInputMethodEvent event; + event.setCommitString(text); + sendInputMethodEvent(&event); + clear(); + // Qt has now put the cursor at the end of the text, corresponding to newCursorPosition == 1 + if (newCursorPosition != 1) { + QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery(); + if (!query.isNull()) { + QList<QInputMethodEvent::Attribute> attributes; + const int localPos = query->value(Qt::ImCursorPosition).toInt(); + const int newLocalPos = newCursorPosition > 0 + ? localPos + newCursorPosition - 1 + : localPos - text.length() + newCursorPosition; + //move the cursor + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, + newLocalPos, 0, QVariant())); + } + } - const int cursorPos = getAbsoluteCursorPosition(query); - m_composingText = text; - m_composingTextStart = cursorPos; - m_composingCursor = cursorPos + text.length(); - finishComposingText(); - //### move cursor to newCursorPosition and call updateCursorPosition() + updateCursorPosition(); return JNI_TRUE; } @@ -624,9 +642,24 @@ jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint right return JNI_TRUE; } +// Android docs say the cursor must not move jboolean QAndroidInputContext::finishComposingText() { - QInputMethodEvent event; + QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery(); + if (query.isNull()) + return JNI_FALSE; + + if (m_composingText.isEmpty()) + return JNI_TRUE; // not composing + + const int blockPos = getBlockPosition(query); + const int localCursorPos = m_composingCursor - blockPos; + + // Moving Qt's cursor to where the preedit cursor used to be + QList<QInputMethodEvent::Attribute> attributes; + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, localCursorPos, 0, QVariant())); + + QInputMethodEvent event(QString(), attributes); event.setCommitString(m_composingText); sendInputMethodEvent(&event); clear(); diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm index dc22da0983..a18f721e04 100644 --- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm @@ -92,16 +92,20 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont) QFont newFont; if (cocoaFont) { int pSize = qRound([cocoaFont pointSize]); - CTFontDescriptorRef font = CTFontCopyFontDescriptor((CTFontRef)cocoaFont); - // QCoreTextFontDatabase::populateFontDatabase() is using localized names - QString family = QCFString::toQString((CFStringRef) CTFontDescriptorCopyLocalizedAttribute(font, kCTFontFamilyNameAttribute, NULL)); - QString style = QCFString::toQString((CFStringRef) CTFontDescriptorCopyLocalizedAttribute(font, kCTFontStyleNameAttribute, NULL)); + QString family(QCFString::toQString([cocoaFont familyName])); + QString typeface(QCFString::toQString([cocoaFont fontName])); + + int hyphenPos = typeface.indexOf(QLatin1Char('-')); + if (hyphenPos != -1) { + typeface.remove(0, hyphenPos + 1); + } else { + typeface = QLatin1String("Normal"); + } - newFont = QFontDatabase().font(family, style, pSize); + newFont = QFontDatabase().font(family, typeface, pSize); newFont.setUnderline(resolveFont.underline()); newFont.setStrikeOut(resolveFont.strikeOut()); - CFRelease(font); } return newFont; } diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 44bc3b8f69..a89979a8ea 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -234,6 +234,10 @@ QCocoaMenu::QCocoaMenu() : QCocoaMenu::~QCocoaMenu() { + foreach (QCocoaMenuItem *item, m_menuItems) { + if (COCOA_MENU_ANCESTOR(item) == this) + SET_COCOA_MENU_ANCESTOR(item, 0); + } QCocoaAutoReleasePool pool; [m_nativeItem setSubmenu:nil]; [m_nativeMenu release]; diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 99d26034bf..9e748bff72 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -106,6 +106,8 @@ QCocoaMenuItem::QCocoaMenuItem() : QCocoaMenuItem::~QCocoaMenuItem() { + if (m_menu && COCOA_MENU_ANCESTOR(m_menu) == this) + SET_COCOA_MENU_ANCESTOR(m_menu, 0); if (m_merged) { [m_native setHidden:YES]; } else { diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm index 57d5c800e0..7322025df6 100644 --- a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm +++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm @@ -463,7 +463,11 @@ bool QCocoaPrintDevice::openPpdFile() ppdClose(m_ppd); m_ppd = 0; CFURLRef ppdURL = NULL; +#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + char ppdPath[PATH_MAX]; +#else char ppdPath[MAXPATHLEN]; +#endif if (PMPrinterCopyDescriptionURL(m_printer, kPMPPDDescriptionType, &ppdURL) == noErr && ppdURL != NULL && CFURLGetFileSystemRepresentation(ppdURL, true, (UInt8*)ppdPath, sizeof(ppdPath))) { diff --git a/src/plugins/platforms/direct2d/direct2d.pro b/src/plugins/platforms/direct2d/direct2d.pro index 439d31fb56..03997f2737 100644 --- a/src/plugins/platforms/direct2d/direct2d.pro +++ b/src/plugins/platforms/direct2d/direct2d.pro @@ -9,7 +9,7 @@ QT *= core-private QT *= gui-private QT *= platformsupport-private -LIBS *= -ld2d1 -ld3d11 -ldwrite +LIBS *= -ld2d1 -ld3d11 -ldwrite -lVersion include(../windows/windows.pri) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp index e4ce81bd24..be013f027b 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 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. @@ -66,6 +66,16 @@ static inline QWindowsDirect2DPlatformPixmap *platformPixmap(QPixmap *p) return static_cast<QWindowsDirect2DPlatformPixmap *>(p->handle()); } +static inline QWindowsDirect2DBitmap *bitmap(QPixmap *p) +{ + return platformPixmap(p)->bitmap(); +} + +static inline QWindowsDirect2DWindow *nativeWindow(QWindow *window) +{ + return static_cast<QWindowsDirect2DWindow *>(window->handle()); +} + QWindowsDirect2DBackingStore::QWindowsDirect2DBackingStore(QWindow *window) : QPlatformBackingStore(window) { @@ -77,36 +87,40 @@ QWindowsDirect2DBackingStore::~QWindowsDirect2DBackingStore() void QWindowsDirect2DBackingStore::beginPaint(const QRegion &) { - platformPixmap(m_pixmap.data())->bitmap()->deviceContext()->begin(); + bitmap(nativeWindow(window())->pixmap())->deviceContext()->begin(); } void QWindowsDirect2DBackingStore::endPaint() { - platformPixmap(m_pixmap.data())->bitmap()->deviceContext()->end(); + bitmap(nativeWindow(window())->pixmap())->deviceContext()->end(); } QPaintDevice *QWindowsDirect2DBackingStore::paintDevice() { - return m_pixmap.data(); + return nativeWindow(window())->pixmap(); } -void QWindowsDirect2DBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) +void QWindowsDirect2DBackingStore::flush(QWindow *targetWindow, const QRegion ®ion, const QPoint &offset) { - QPlatformWindow *pw = window->handle(); - if (pw && m_pixmap) - static_cast<QWindowsDirect2DWindow *>(pw)->flush(platformPixmap(m_pixmap.data())->bitmap(), region, offset); + if (targetWindow != window()) { + QSharedPointer<QWindowsDirect2DBitmap> copy(nativeWindow(window())->copyBackBuffer()); + nativeWindow(targetWindow)->flush(copy.data(), region, offset); + } + + nativeWindow(targetWindow)->present(); } void QWindowsDirect2DBackingStore::resize(const QSize &size, const QRegion ®ion) { - Q_UNUSED(region); + QPixmap old = nativeWindow(window())->pixmap()->copy(); - QScopedPointer<QPixmap> oldPixmap(m_pixmap.take()); - m_pixmap.reset(new QPixmap(size.width(), size.height())); + nativeWindow(window())->resizeSwapChain(size); + QPixmap *newPixmap = nativeWindow(window())->pixmap(); - if (oldPixmap) { - foreach (const QRect &rect, region.rects()) - platformPixmap(m_pixmap.data())->copy(oldPixmap->handle(), rect); + if (!old.isNull()) { + foreach (const QRect &rect, region.rects()) { + platformPixmap(newPixmap)->copy(old.handle(), rect); + } } } diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h index fc6802aaa2..71e9437274 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 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. @@ -50,6 +50,8 @@ QT_BEGIN_NAMESPACE +class QWindowsDirect2DWindow; + class QWindowsDirect2DBackingStore : public QPlatformBackingStore { Q_DISABLE_COPY(QWindowsDirect2DBackingStore) @@ -62,11 +64,8 @@ public: void endPaint(); QPaintDevice *paintDevice() Q_DECL_OVERRIDE; - void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; + void flush(QWindow *targetWindow, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE; - -private: - QScopedPointer<QPixmap> m_pixmap; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp index 58002fb0dd..80688a1da7 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp @@ -99,7 +99,7 @@ public: return false; } - hr = dxgiDevice->GetParent(IID_PPV_ARGS(&dxgiAdapter)); + hr = dxgiDevice->GetAdapter(&dxgiAdapter); if (FAILED(hr)) { qWarning("%s: Failed to probe DXGI Device for parent DXGI Adapter: %#x", __FUNCTION__, hr); return false; diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp index 1a26d7029e..44fc7aa927 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp @@ -48,7 +48,8 @@ #include "qwindowscontext.h" -#include <QtCore/QDebug> +#include <qplatformdefs.h> +#include <QtCore/QCoreApplication> #include <QtGui/private/qpixmap_raster_p.h> #include <QtGui/qpa/qwindowsysteminterface.h> @@ -61,8 +62,140 @@ public: QWindowsDirect2DContext m_d2dContext; }; +class Direct2DVersion +{ +private: + Direct2DVersion() + : partOne(0) + , partTwo(0) + , partThree(0) + , partFour(0) + {} + + Direct2DVersion(int one, int two, int three, int four) + : partOne(one) + , partTwo(two) + , partThree(three) + , partFour(four) + {} + +public: + // 6.2.9200.16765 corresponds to Direct2D 1.1 on Windows 7 SP1 with Platform Update + enum { + D2DMinVersionPart1 = 6, + D2DMinVersionPart2 = 2, + D2DMinVersionPart3 = 9200, + D2DMinVersionPart4 = 16765 + }; + + static Direct2DVersion systemVersion() { + static const int bufSize = 512; + TCHAR filename[bufSize]; + + UINT i = GetSystemDirectory(filename, bufSize); + if (i > 0 && i < MAX_PATH) { + if (_tcscat_s(filename, MAX_PATH, __TEXT("\\d2d1.dll")) == 0) { + DWORD versionInfoSize = GetFileVersionInfoSize(filename, NULL); + if (versionInfoSize) { + QVector<BYTE> info(versionInfoSize); + if (GetFileVersionInfo(filename, NULL, versionInfoSize, info.data())) { + UINT size; + DWORD *fi; + + if (VerQueryValue(info.constData(), __TEXT("\\"), (LPVOID *) &fi, &size) && size) { + VS_FIXEDFILEINFO *verInfo = (VS_FIXEDFILEINFO *) fi; + return Direct2DVersion(HIWORD(verInfo->dwFileVersionMS), + LOWORD(verInfo->dwFileVersionMS), + HIWORD(verInfo->dwFileVersionLS), + LOWORD(verInfo->dwFileVersionLS)); + } + } + } + } + } + + return Direct2DVersion(); + } + + static Direct2DVersion minimumVersion() { + return Direct2DVersion(D2DMinVersionPart1, + D2DMinVersionPart2, + D2DMinVersionPart3, + D2DMinVersionPart4); + } + + bool isValid() const { + return partOne || partTwo || partThree || partFour; + } + + bool operator<(const Direct2DVersion &other) { + int c = cmp(partOne, other.partOne); + if (c > 0) + return false; + if (c < 0) + return true; + + c = cmp(partTwo, other.partTwo); + if (c > 0) + return false; + if (c < 0) + return true; + + c = cmp(partThree, other.partThree); + if (c > 0) + return false; + if (c < 0) + return true; + + c = cmp(partFour, other.partFour); + if (c > 0) + return false; + if (c < 0) + return true; + + return false; + } + + static Q_DECL_CONSTEXPR int cmp(int a, int b) { + return a - b; + } + + int partOne, partTwo, partThree, partFour; +}; + QWindowsDirect2DIntegration *QWindowsDirect2DIntegration::create(const QStringList ¶mList) { + Direct2DVersion systemVersion = Direct2DVersion::systemVersion(); + + if (systemVersion.isValid() && systemVersion < Direct2DVersion::minimumVersion()) { + QString msg = QCoreApplication::translate("QWindowsDirect2DIntegration", + "Qt cannot load the direct2d platform plugin because " \ + "the Direct2D version on this system is too old. The " \ + "minimum system requirement for this platform plugin " \ + "is Windows 7 SP1 with Platform Update.\n\n" \ + "The minimum Direct2D version required is %1.%2.%3.%4. " \ + "The Direct2D version on this system is %5.%6.%7.%8."); + + msg = msg.arg(Direct2DVersion::D2DMinVersionPart1) + .arg(Direct2DVersion::D2DMinVersionPart2) + .arg(Direct2DVersion::D2DMinVersionPart3) + .arg(Direct2DVersion::D2DMinVersionPart4) + .arg(systemVersion.partOne) + .arg(systemVersion.partTwo) + .arg(systemVersion.partThree) + .arg(systemVersion.partFour); + + QString caption = QCoreApplication::translate("QWindowsDirect2DIntegration", + "Cannot load direct2d platform plugin"); + + MessageBoxW(NULL, + msg.toStdWString().c_str(), + caption.toStdWString().c_str(), + MB_OK | MB_ICONERROR); + + return Q_NULLPTR; + } + QWindowsDirect2DIntegration *integration = new QWindowsDirect2DIntegration(paramList); if (!integration->init()) { diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index 58c30b6eeb..6e8d9b0baf 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -58,7 +58,6 @@ #include <QtGui/private/qfontengine_p.h> #include <QtGui/private/qstatictext_p.h> -#include <wrl.h> using Microsoft::WRL::ComPtr; QT_BEGIN_NAMESPACE @@ -346,6 +345,8 @@ public: QPointF currentBrushOrigin; + QHash< QFont, ComPtr<IDWriteFontFace> > fontCache; + struct { bool emulate; QPen qpen; @@ -1291,44 +1292,6 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r, } } -static ComPtr<IDWriteFontFace> fontFaceFromFontEngine(QFontEngine *fe) -{ - ComPtr<IDWriteFontFace> fontFace; - - switch (fe->type()) { - case QFontEngine::Win: - { - QWindowsFontEngine *wfe = static_cast<QWindowsFontEngine *>(fe); - 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 *>(fe); - fontFace = wfedw->directWriteFontFace(); - } - break; - -#endif // QT_NO_DIRECTWRITE - - default: - qWarning("%s: Unknown font engine!", __FUNCTION__); - break; - } - - return fontFace; -} - void QWindowsDirect2DPaintEngine::drawStaticTextItem(QStaticTextItem *staticTextItem) { Q_D(QWindowsDirect2DPaintEngine); @@ -1340,24 +1303,22 @@ void QWindowsDirect2DPaintEngine::drawStaticTextItem(QStaticTextItem *staticText ensurePen(); // 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 ((state()->transform().isAffine() == false) || d->pen.emulate) { + if (emulationRequired(PenEmulation)) { QPaintEngineEx::drawStaticTextItem(staticTextItem); return; } - ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(staticTextItem->fontEngine()); + ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(staticTextItem->font, staticTextItem->fontEngine()); if (!fontFace) { qWarning("%s: Could not find font - falling back to slow text rendering path.", __FUNCTION__); QPaintEngineEx::drawStaticTextItem(staticTextItem); return; } - QVector<UINT16> glyphIndices(staticTextItem->numGlyphs); - QVector<FLOAT> glyphAdvances(staticTextItem->numGlyphs); - QVector<DWRITE_GLYPH_OFFSET> glyphOffsets(staticTextItem->numGlyphs); + QVarLengthArray<UINT16> glyphIndices(staticTextItem->numGlyphs); + QVarLengthArray<FLOAT> glyphAdvances(staticTextItem->numGlyphs); + QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(staticTextItem->numGlyphs); - // XXX Are we generating a lot of cache misses here? for (int i = 0; i < staticTextItem->numGlyphs; i++) { glyphIndices[i] = UINT16(staticTextItem->glyphs[i]); // Imperfect conversion here @@ -1390,24 +1351,22 @@ void QWindowsDirect2DPaintEngine::drawTextItem(const QPointF &p, const QTextItem ensurePen(); // 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 ((state()->transform().isAffine() == false) || d->pen.emulate) { + if (emulationRequired(PenEmulation)) { QPaintEngine::drawTextItem(p, textItem); return; } - ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(ti.fontEngine); + ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(*ti.f, ti.fontEngine); if (!fontFace) { qWarning("%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); + QVarLengthArray<UINT16> glyphIndices(ti.glyphs.numGlyphs); + QVarLengthArray<FLOAT> glyphAdvances(ti.glyphs.numGlyphs); + QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(ti.glyphs.numGlyphs); - // XXX Are we generating a lot of cache misses here? for (int i = 0; i < ti.glyphs.numGlyphs; i++) { glyphIndices[i] = UINT16(ti.glyphs.glyphs[i]); // Imperfect conversion here glyphAdvances[i] = ti.glyphs.effectiveAdvance(i).toReal(); @@ -1618,4 +1577,49 @@ void QWindowsDirect2DPaintEngine::adjustForAliasing(QPointF *point) (*point) += adjustment; } +Microsoft::WRL::ComPtr<IDWriteFontFace> QWindowsDirect2DPaintEngine::fontFaceFromFontEngine(const QFont &font, QFontEngine *fe) +{ + Q_D(QWindowsDirect2DPaintEngine); + + ComPtr<IDWriteFontFace> fontFace = d->fontCache.value(font); + if (fontFace) + return fontFace; + + switch (fe->type()) { + case QFontEngine::Win: + { + QWindowsFontEngine *wfe = static_cast<QWindowsFontEngine *>(fe); + 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 *>(fe); + fontFace = wfedw->directWriteFontFace(); + } + break; + +#endif // QT_NO_DIRECTWRITE + + default: + qWarning("%s: Unknown font engine!", __FUNCTION__); + break; + } + + if (fontFace) + d->fontCache.insert(font, fontFace); + + return fontFace; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h index badd7a7688..fb9b7acec3 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h @@ -47,6 +47,7 @@ #include <d2d1_1.h> #include <dwrite_1.h> +#include <wrl.h> QT_BEGIN_NAMESPACE @@ -114,6 +115,8 @@ private: bool antiAliasingEnabled() const; void adjustForAliasing(QRectF *rect); void adjustForAliasing(QPointF *point); + + Microsoft::WRL::ComPtr<IDWriteFontFace> fontFaceFromFontEngine(const QFont &font, QFontEngine *fe); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp index 072c4b3c0e..d9f7c595ca 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 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. @@ -56,12 +56,27 @@ class QWindowsDirect2DPlatformPixmapPrivate { public: QWindowsDirect2DPlatformPixmapPrivate() - : bitmap(new QWindowsDirect2DBitmap) - , device(new QWindowsDirect2DPaintDevice(bitmap.data(), QInternal::Pixmap)) + : owns_bitmap(true) + , bitmap(new QWindowsDirect2DBitmap) + , device(new QWindowsDirect2DPaintDevice(bitmap, QInternal::Pixmap)) , devicePixelRatio(1.0) {} - QScopedPointer<QWindowsDirect2DBitmap> bitmap; + QWindowsDirect2DPlatformPixmapPrivate(QWindowsDirect2DBitmap *bitmap) + : owns_bitmap(false) + , bitmap(bitmap) + , device(new QWindowsDirect2DPaintDevice(bitmap, QInternal::Pixmap)) + , devicePixelRatio(1.0) + {} + + ~QWindowsDirect2DPlatformPixmapPrivate() + { + if (owns_bitmap) + delete bitmap; + } + + bool owns_bitmap; + QWindowsDirect2DBitmap *bitmap; QScopedPointer<QWindowsDirect2DPaintDevice> device; qreal devicePixelRatio; }; @@ -75,6 +90,19 @@ QWindowsDirect2DPlatformPixmap::QWindowsDirect2DPlatformPixmap(PixelType pixelTy setSerialNumber(qt_d2dpixmap_serno++); } +QWindowsDirect2DPlatformPixmap::QWindowsDirect2DPlatformPixmap(QPlatformPixmap::PixelType pixelType, + QWindowsDirect2DBitmap *bitmap) + : QPlatformPixmap(pixelType, Direct2DClass) + , d_ptr(new QWindowsDirect2DPlatformPixmapPrivate(bitmap)) +{ + setSerialNumber(qt_d2dpixmap_serno++); + + is_null = false; + w = bitmap->size().width(); + h = bitmap->size().height(); + this->d = 32; +} + QWindowsDirect2DPlatformPixmap::~QWindowsDirect2DPlatformPixmap() { @@ -173,7 +201,7 @@ void QWindowsDirect2DPlatformPixmap::setDevicePixelRatio(qreal scaleFactor) QWindowsDirect2DBitmap *QWindowsDirect2DPlatformPixmap::bitmap() const { Q_D(const QWindowsDirect2DPlatformPixmap); - return d->bitmap.data(); + return d->bitmap; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h index e6684ea423..1936ef0622 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 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. @@ -55,6 +55,9 @@ class QWindowsDirect2DPlatformPixmap : public QPlatformPixmap Q_DECLARE_PRIVATE(QWindowsDirect2DPlatformPixmap) public: QWindowsDirect2DPlatformPixmap(PixelType pixelType); + + // We do NOT take ownership of the bitmap through this constructor! + QWindowsDirect2DPlatformPixmap(PixelType pixelType, QWindowsDirect2DBitmap *bitmap); ~QWindowsDirect2DPlatformPixmap(); virtual void resize(int width, int height); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp index 50d0cb81f5..15ec0c3526 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp @@ -43,6 +43,7 @@ #include "qwindowsdirect2dwindow.h" #include "qwindowsdirect2ddevicecontext.h" #include "qwindowsdirect2dhelpers.h" +#include "qwindowsdirect2dplatformpixmap.h" #include <d3d11.h> #include <d2d1_1.h> @@ -87,6 +88,13 @@ QWindowsDirect2DWindow::~QWindowsDirect2DWindow() { } +QPixmap *QWindowsDirect2DWindow::pixmap() +{ + setupBitmap(); + + return m_pixmap.data(); +} + void QWindowsDirect2DWindow::flush(QWindowsDirect2DBitmap *bitmap, const QRegion ®ion, const QPoint &offset) { DXGI_SWAP_CHAIN_DESC1 desc; @@ -102,32 +110,38 @@ void QWindowsDirect2DWindow::flush(QWindowsDirect2DBitmap *bitmap, const QRegion if (!m_bitmap) return; - m_bitmap->deviceContext()->begin(); - - ID2D1DeviceContext *dc = m_bitmap->deviceContext()->get(); - if (!m_needsFullFlush) { - QRegion clipped = region; - clipped &= QRect(0, 0, desc.Width, desc.Height); - - foreach (const QRect &rect, clipped.rects()) { - QRectF rectF(rect); + if (bitmap != m_bitmap.data()) { + m_bitmap->deviceContext()->begin(); + + ID2D1DeviceContext *dc = m_bitmap->deviceContext()->get(); + if (!m_needsFullFlush) { + QRegion clipped = region; + clipped &= QRect(0, 0, desc.Width, desc.Height); + + foreach (const QRect &rect, clipped.rects()) { + QRectF rectF(rect); + dc->DrawBitmap(bitmap->bitmap(), + to_d2d_rect_f(rectF), + 1.0, + D2D1_INTERPOLATION_MODE_LINEAR, + to_d2d_rect_f(rectF.translated(offset.x(), offset.y()))); + } + } else { + QRectF rectF(0, 0, desc.Width, desc.Height); dc->DrawBitmap(bitmap->bitmap(), to_d2d_rect_f(rectF), 1.0, D2D1_INTERPOLATION_MODE_LINEAR, to_d2d_rect_f(rectF.translated(offset.x(), offset.y()))); + m_needsFullFlush = false; } - } else { - QRectF rectF(0, 0, desc.Width, desc.Height); - dc->DrawBitmap(bitmap->bitmap(), - to_d2d_rect_f(rectF), - 1.0, - D2D1_INTERPOLATION_MODE_LINEAR, - to_d2d_rect_f(rectF.translated(offset.x(), offset.y()))); - m_needsFullFlush = false; + + m_bitmap->deviceContext()->end(); } +} - m_bitmap->deviceContext()->end(); +void QWindowsDirect2DWindow::present() +{ m_swapChain->Present(0, 0); } @@ -136,6 +150,7 @@ void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size) if (!m_swapChain) return; + m_pixmap.reset(); m_bitmap.reset(); m_deviceContext->SetTarget(Q_NULLPTR); @@ -149,6 +164,43 @@ void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size) m_needsFullFlush = true; } +QSharedPointer<QWindowsDirect2DBitmap> QWindowsDirect2DWindow::copyBackBuffer() const +{ + const QSharedPointer<QWindowsDirect2DBitmap> null_result; + + if (!m_bitmap) + return null_result; + + D2D1_PIXEL_FORMAT format = m_bitmap->bitmap()->GetPixelFormat(); + D2D1_SIZE_U size = m_bitmap->bitmap()->GetPixelSize(); + + FLOAT dpiX, dpiY; + m_bitmap->bitmap()->GetDpi(&dpiX, &dpiY); + + D2D1_BITMAP_PROPERTIES1 properties = { + format, // D2D1_PIXEL_FORMAT pixelFormat; + dpiX, // FLOAT dpiX; + dpiY, // FLOAT dpiY; + D2D1_BITMAP_OPTIONS_TARGET, // D2D1_BITMAP_OPTIONS bitmapOptions; + Q_NULLPTR // _Field_size_opt_(1) ID2D1ColorContext *colorContext; + }; + ComPtr<ID2D1Bitmap1> copy; + HRESULT hr = m_deviceContext.Get()->CreateBitmap(size, NULL, 0, properties, ©); + + if (FAILED(hr)) { + qWarning("%s: Could not create staging bitmap: %#x", __FUNCTION__, hr); + return null_result; + } + + hr = copy.Get()->CopyFromBitmap(NULL, m_bitmap->bitmap(), NULL); + if (FAILED(hr)) { + qWarning("%s: Could not copy from bitmap! %#x", __FUNCTION__, hr); + return null_result; + } + + return QSharedPointer<QWindowsDirect2DBitmap>(new QWindowsDirect2DBitmap(copy.Get(), Q_NULLPTR)); +} + void QWindowsDirect2DWindow::setupBitmap() { if (m_bitmap) @@ -175,6 +227,10 @@ void QWindowsDirect2DWindow::setupBitmap() } m_bitmap.reset(new QWindowsDirect2DBitmap(backBufferBitmap.Get(), m_deviceContext.Get())); + + QWindowsDirect2DPlatformPixmap *pp = new QWindowsDirect2DPlatformPixmap(QPlatformPixmap::PixmapType, + m_bitmap.data()); + m_pixmap.reset(new QPixmap(pp)); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h index 7996904639..47c790da5d 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h @@ -56,16 +56,21 @@ public: QWindowsDirect2DWindow(QWindow *window, const QWindowsWindowData &data); ~QWindowsDirect2DWindow(); + QPixmap *pixmap(); void flush(QWindowsDirect2DBitmap *bitmap, const QRegion ®ion, const QPoint &offset); + void present(); + void resizeSwapChain(const QSize &size); + + QSharedPointer<QWindowsDirect2DBitmap> copyBackBuffer() const; private: - void resizeSwapChain(const QSize &size); void setupBitmap(); private: Microsoft::WRL::ComPtr<IDXGISwapChain1> m_swapChain; Microsoft::WRL::ComPtr<ID2D1DeviceContext> m_deviceContext; QScopedPointer<QWindowsDirect2DBitmap> m_bitmap; + QScopedPointer<QPixmap> m_pixmap; bool m_needsFullFlush; }; diff --git a/src/plugins/platforms/ios/qiosapplicationstate.mm b/src/plugins/platforms/ios/qiosapplicationstate.mm index 8d77e608e5..afa3ecb21f 100644 --- a/src/plugins/platforms/ios/qiosapplicationstate.mm +++ b/src/plugins/platforms/ios/qiosapplicationstate.mm @@ -150,6 +150,7 @@ break; } QWindowSystemInterface::handleApplicationStateChanged(state); + QWindowSystemInterface::flushWindowSystemEvents(); } @end diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index fc99543aa6..6b6892e6e4 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -88,6 +88,7 @@ public: WId winId() const { return WId(m_view); }; private: + void applicationStateChanged(Qt::ApplicationState state); void applyGeometry(const QRect &rect); QUIView *m_view; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 7d5c507972..6f5c96cfc1 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -192,12 +192,25 @@ - (void)displayLayer:(CALayer *)layer { - QSize bounds = fromCGRect(layer.bounds).toRect().size(); + Q_UNUSED(layer); + Q_ASSERT(layer == self.layer); - Q_ASSERT(m_qioswindow->geometry().size() == bounds); - Q_ASSERT(self.hidden == !m_qioswindow->window()->isVisible()); + [self sendUpdatedExposeEvent]; +} + +- (void)sendUpdatedExposeEvent +{ + QRegion region; + + if (m_qioswindow->isExposed()) { + QSize bounds = fromCGRect(self.layer.bounds).toRect().size(); + + Q_ASSERT(m_qioswindow->geometry().size() == bounds); + Q_ASSERT(self.hidden == !m_qioswindow->window()->isVisible()); + + region = QRect(QPoint(), bounds); + } - QRegion region = self.hidden ? QRegion() : QRect(QPoint(), bounds); QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region); QWindowSystemInterface::flushWindowSystemEvents(); } @@ -279,19 +292,33 @@ - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { - if (!touches && m_activeTouches.isEmpty()) + if (m_activeTouches.isEmpty()) return; - if (!touches) { - m_activeTouches.clear(); - } else { - for (UITouch *touch in touches) - m_activeTouches.remove(touch); - - Q_ASSERT_X(m_activeTouches.isEmpty(), Q_FUNC_INFO, - "Subset of active touches cancelled by UIKit"); - } - + // When four-finger swiping, we get a touchesCancelled callback + // which includes all four touch points. The swipe gesture is + // then active until all four touches have been released, and + // we start getting touchesBegan events again. + + // When five-finger pinching, we also get a touchesCancelled + // callback with all five touch points, but the pinch gesture + // ends when the second to last finger is released from the + // screen. The last finger will not emit any more touch + // events, _but_, will contribute to starting another pinch + // gesture. That second pinch gesture will _not_ trigger a + // touchesCancelled event when starting, but as each finger + // is released, and we may get touchesMoved events for the + // remaining fingers. [event allTouches] also contains one + // less touch point than it should, so this behavior is + // likely a bug in the iOS system gesture recognizer, but we + // have to take it into account when maintaining the Qt state. + // We do this by assuming that there are no cases where a + // sub-set of the active touch events are intentionally cancelled. + + if (touches && (static_cast<NSInteger>([touches count]) != m_activeTouches.count())) + qWarning("Subset of active touches cancelled by UIKit"); + + m_activeTouches.clear(); m_nextTouchId = 0; NSTimeInterval timestamp = event ? event.timestamp : [[NSProcessInfo processInfo] systemUptime]; @@ -334,6 +361,8 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_view([[QUIView alloc] initWithQIOSWindow:this]) , m_windowLevel(0) { + connect(qGuiApp, &QGuiApplication::applicationStateChanged, this, &QIOSWindow::applicationStateChanged); + setParent(QPlatformWindow::parent()); // Resolve default window geometry in case it was not set before creating the @@ -471,7 +500,8 @@ void QIOSWindow::applyGeometry(const QRect &rect) bool QIOSWindow::isExposed() const { - return window()->isVisible() && !window()->geometry().isEmpty(); + return qApp->applicationState() > Qt::ApplicationHidden + && window()->isVisible() && !window()->geometry().isEmpty(); } void QIOSWindow::setWindowState(Qt::WindowState state) @@ -593,6 +623,12 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; } +void QIOSWindow::applicationStateChanged(Qt::ApplicationState) +{ + if (window()->isExposed() != isExposed()) + [m_view sendUpdatedExposeEvent]; +} + qreal QIOSWindow::devicePixelRatio() const { return m_view.contentScaleFactor; diff --git a/src/plugins/platforms/kms/qkmsdevice.cpp b/src/plugins/platforms/kms/qkmsdevice.cpp index 1e08c6f301..8e669fe7d5 100644 --- a/src/plugins/platforms/kms/qkmsdevice.cpp +++ b/src/plugins/platforms/kms/qkmsdevice.cpp @@ -85,8 +85,7 @@ QKmsDevice::~QKmsDevice() void QKmsDevice::createScreens() { - drmModeRes *resources = 0; - resources = drmModeGetResources(m_fd); + drmModeRes *resources = drmModeGetResources(m_fd); if (!resources) qFatal("drmModeGetResources failed"); @@ -95,7 +94,7 @@ void QKmsDevice::createScreens() drmModeConnector *connector = 0; connector = drmModeGetConnector(m_fd, resources->connectors[i]); if (connector && connector->connection == DRM_MODE_CONNECTED) { - m_integration->addScreen(new QKmsScreen(this, connector->connector_id)); + m_integration->addScreen(new QKmsScreen(this, resources, connector)); } drmModeFreeConnector(connector); } diff --git a/src/plugins/platforms/kms/qkmsscreen.cpp b/src/plugins/platforms/kms/qkmsscreen.cpp index ad1a45b459..a930aa6545 100644 --- a/src/plugins/platforms/kms/qkmsscreen.cpp +++ b/src/plugins/platforms/kms/qkmsscreen.cpp @@ -63,18 +63,18 @@ static drmModeModeInfo builtin_1024x768 = { "1024x768" }; -QKmsScreen::QKmsScreen(QKmsDevice *device, int connectorId) +QKmsScreen::QKmsScreen(QKmsDevice *device, const drmModeRes *resources, const drmModeConnector *connector) : m_device(device), m_current_bo(0), m_next_bo(0), - m_connectorId(connectorId), + m_connectorId(connector->connector_id), m_depth(32), m_format(QImage::Format_Invalid), m_eglWindowSurface(EGL_NO_SURFACE), m_modeSet(false) { m_cursor = new QKmsCursor(this); - initializeScreenMode(); + initializeScreenMode(resources, connector); } QKmsScreen::~QKmsScreen() @@ -114,14 +114,9 @@ QPlatformCursor *QKmsScreen::cursor() const return m_cursor; } -void QKmsScreen::initializeScreenMode() +void QKmsScreen::initializeScreenMode(const drmModeRes *resources, const drmModeConnector *connector) { //Determine optimal mode for screen - drmModeRes *resources = drmModeGetResources(m_device->fd()); - if (!resources) - qFatal("drmModeGetResources failed"); - - drmModeConnector *connector = drmModeGetConnector(m_device->fd(), m_connectorId); drmModeModeInfo *mode = 0; for (int i = 0; i < connector->count_modes; ++i) { if (connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) { @@ -129,8 +124,12 @@ void QKmsScreen::initializeScreenMode() break; } } - if (!mode) - mode = &builtin_1024x768; + if (!mode) { + if (connector->count_modes > 0) + mode = &connector->modes[0]; + else + mode = &builtin_1024x768; + } drmModeEncoder *encoder = drmModeGetEncoder(m_device->fd(), connector->encoders[0]); if (encoder == 0) @@ -162,8 +161,6 @@ void QKmsScreen::initializeScreenMode() qDebug() << "created gbm surface" << m_gbmSurface << m_mode.hdisplay << m_mode.vdisplay; //Cleanup drmModeFreeEncoder(encoder); - drmModeFreeConnector(connector); - drmModeFreeResources(resources); } QSurfaceFormat QKmsScreen::tweakFormat(const QSurfaceFormat &format) diff --git a/src/plugins/platforms/kms/qkmsscreen.h b/src/plugins/platforms/kms/qkmsscreen.h index 5ae5a1062b..1fa8dbb763 100644 --- a/src/plugins/platforms/kms/qkmsscreen.h +++ b/src/plugins/platforms/kms/qkmsscreen.h @@ -68,7 +68,7 @@ class QKmsContext; class QKmsScreen : public QPlatformScreen { public: - QKmsScreen(QKmsDevice *device, int connectorId); + QKmsScreen(QKmsDevice *device, const drmModeRes *resources, const drmModeConnector *connector); ~QKmsScreen(); QRect geometry() const; @@ -94,7 +94,7 @@ public: private: void performPageFlip(); - void initializeScreenMode(); + void initializeScreenMode(const drmModeRes *resources, const drmModeConnector *connector); QKmsDevice *m_device; gbm_bo *m_current_bo; diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp index 1abf447709..34a9c1df5f 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp +++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp @@ -145,9 +145,8 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion ®ion) << " from: " << (m_image.isNull() ? QSize() : m_image->image().size()); } #endif - QImage::Format format = QWindowsNativeImage::systemFormat(); - if (format == QImage::Format_RGB32 && window()->format().hasAlpha()) - format = QImage::Format_ARGB32_Premultiplied; + const QImage::Format format = window()->format().hasAlpha() ? + QImage::Format_ARGB32_Premultiplied : QWindowsNativeImage::systemFormat(); QWindowsNativeImage *oldwni = m_image.data(); QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format); diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index 29c43fc7a5..6f97c8584b 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -169,6 +169,20 @@ bool QWindowsFontEngine::hasCMapTable() const return GetFontData(hdc, MAKE_TAG('c', 'm', 'a', 'p'), 0, 0, 0) != GDI_ERROR; } +bool QWindowsFontEngine::hasGlyfTable() const +{ + HDC hdc = m_fontEngineData->hdc; + SelectObject(hdc, hfont); + return GetFontData(hdc, MAKE_TAG('g', 'l', 'y', 'f'), 0, 0, 0) != GDI_ERROR; +} + +bool QWindowsFontEngine::hasEbdtTable() const +{ + HDC hdc = m_fontEngineData->hdc; + SelectObject(hdc, hfont); + return GetFontData(hdc, MAKE_TAG('E', 'B', 'D', 'T'), 0, 0, 0) != GDI_ERROR; +} + void QWindowsFontEngine::getCMap() { ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE) || hasCMapTable(); @@ -308,6 +322,8 @@ QWindowsFontEngine::QWindowsFontEngine(const QString &name, userData.insert(QStringLiteral("hFont"), QVariant::fromValue(hfont)); userData.insert(QStringLiteral("trueType"), QVariant(bool(ttf))); setUserData(userData); + + hasUnreliableOutline = hasGlyfTable() && hasEbdtTable(); } QWindowsFontEngine::~QWindowsFontEngine() @@ -662,6 +678,11 @@ void QWindowsFontEngine::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qre } #endif // Q_CC_MINGW +bool QWindowsFontEngine::hasUnreliableGlyphOutline() const +{ + return hasUnreliableOutline; +} + qreal QWindowsFontEngine::minLeftBearing() const { if (lbearing == SHRT_MIN) diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h index 7a0803830c..0ddf778fa0 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.h +++ b/src/plugins/platforms/windows/qwindowsfontengine.h @@ -122,6 +122,8 @@ public: virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0); #endif + bool hasUnreliableGlyphOutline() const Q_DECL_OVERRIDE; + int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs) const; void getCMap(); @@ -136,6 +138,8 @@ private: QImage::Format mask_format); bool hasCFFTable() const; bool hasCMapTable() const; + bool hasGlyfTable() const; + bool hasEbdtTable() const; const QSharedPointer<QWindowsFontEngineData> m_fontEngineData; @@ -146,6 +150,7 @@ private: uint stockFont : 1; uint ttf : 1; uint hasOutline : 1; + uint hasUnreliableOutline : 1; uint cffTable : 1; TEXTMETRIC tm; int lw; diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 583441f396..773220660a 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -496,6 +496,7 @@ QWinRTScreen::QWinRTScreen(ICoreWindow *window) // Set initial orientation onOrientationChanged(0); + setOrientationUpdateMask(m_nativeOrientation); m_displayProperties->add_OrientationChanged(Callback<IDisplayPropertiesEventHandler>(this, &QWinRTScreen::onOrientationChanged).Get(), &m_tokens[QEvent::OrientationChange]); diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index 30d5c911e7..7304930b8b 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -419,7 +419,7 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share, const return; } m_format = QSurfaceFormat(); - m_format.setRenderableType(QOpenGLContext::openGLModuleType() == QOpenGLContext::DesktopGL + m_format.setRenderableType(QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL ? QSurfaceFormat::OpenGL : QSurfaceFormat::OpenGLES); updateFormatFromContext(m_format); if (vinfo) diff --git a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro index 19852b74b1..dfdcb2e83a 100644 --- a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro +++ b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro @@ -3,9 +3,8 @@ # libxcb-fixes, libxcb-randr, libxcb-shm, libxcb-sync, libxcb-image, # libxcb-keysyms, libxcb-icccm, libxcb-renderutil, libxcb-xkb # -TEMPLATE = lib -TARGET = xcb-static -CONFIG += staticlib +CONFIG += static +load(qt_helper_lib) XCB_DIR = ../../../../3rdparty/xcb diff --git a/src/plugins/printsupport/printsupport.pro b/src/plugins/printsupport/printsupport.pro index 93f3d65bc5..ed201f0744 100644 --- a/src/plugins/printsupport/printsupport.pro +++ b/src/plugins/printsupport/printsupport.pro @@ -1,5 +1,5 @@ TEMPLATE = subdirs -mac: SUBDIRS += cocoa +osx: SUBDIRS += cocoa win32: SUBDIRS += windows unix:!mac:contains(QT_CONFIG, cups): SUBDIRS += cups |