From 6320ca79e956241f9dfab829be9cb3800339fdb3 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 7 Sep 2016 10:40:20 +0200 Subject: Fix test for sandboxed targets Instead of creating files relative to the application binary, use a temporary directory. This also cleans up the test data after execution. Change-Id: I5d680fd01c60b0d33df06f9cb9aaef7c86279710 Reviewed-by: Jesus Fernandez Reviewed-by: Oliver Wolff --- .../gui/kernel/qfileopenevent/test/tst_qfileopenevent.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/auto/gui/kernel/qfileopenevent/test/tst_qfileopenevent.cpp b/tests/auto/gui/kernel/qfileopenevent/test/tst_qfileopenevent.cpp index 9d42ae5850..43b2b79698 100644 --- a/tests/auto/gui/kernel/qfileopenevent/test/tst_qfileopenevent.cpp +++ b/tests/auto/gui/kernel/qfileopenevent/test/tst_qfileopenevent.cpp @@ -26,6 +26,7 @@ ** ****************************************************************************/ +#include #include #include @@ -38,6 +39,7 @@ public: public slots: void initTestCase(); + void cleanupTestCase(); private slots: void constructor(); @@ -54,6 +56,9 @@ private: bool appendFileContent(QFileOpenEvent& event, const QByteArray& writeContent); bool event(QEvent *); + + QTemporaryDir m_temporaryDir; + QString m_originalCurrent; }; tst_qfileopenevent::~tst_qfileopenevent() @@ -62,6 +67,13 @@ tst_qfileopenevent::~tst_qfileopenevent() void tst_qfileopenevent::initTestCase() { + m_originalCurrent = QDir::currentPath(); + QDir::setCurrent(m_temporaryDir.path()); +} + +void tst_qfileopenevent::cleanupTestCase() +{ + QDir::setCurrent(m_originalCurrent); } void tst_qfileopenevent::createFile(const QString &filename, const QByteArray &content) -- cgit v1.2.3 From 60da6313cf990ebf341cc688b20fd60a67f53dd2 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 9 Sep 2016 13:55:57 +0200 Subject: winrt: Fix initialization of input context f104e43a72380f66f8c517b90326a9209612106d moved QWinRTInputContext to the gui thread. However, IInputPane needs to be queried from Xaml itself. Otherwise it might cause unhandled exceptions. Change-Id: I43848c796e7ff163e6befa7c58f0ad68445b9865 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtinputcontext.cpp | 35 +++++++++++----------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp index 968c47f2c2..63e5b0cf27 100644 --- a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp @@ -86,30 +86,31 @@ QWinRTInputContext::QWinRTInputContext(QWinRTScreen *screen) { qCDebug(lcQpaInputMethods) << __FUNCTION__ << screen; - ComPtr statics; - if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(), - &statics))) { - qWarning("failed to retrieve input pane statics."); - return; - } + QEventDispatcherWinRT::runOnXamlThread([this]() { + ComPtr statics; + if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(), + &statics))) { + qWarning("failed to retrieve input pane statics."); + return S_OK; + } - ComPtr inputPane; - statics->GetForCurrentView(&inputPane); - if (inputPane) { - QEventDispatcherWinRT::runOnXamlThread([this, inputPane]() { + ComPtr inputPane; + statics->GetForCurrentView(&inputPane); + if (inputPane) { EventRegistrationToken showToken, hideToken; inputPane->add_Showing(Callback( this, &QWinRTInputContext::onShowing).Get(), &showToken); inputPane->add_Hiding(Callback( this, &QWinRTInputContext::onHiding).Get(), &hideToken); - return S_OK; - }); - m_keyboardRect = getInputPaneRect(inputPane, m_screen->scaleFactor()); - m_isInputPanelVisible = !m_keyboardRect.isEmpty(); - } else { - qWarning("failed to retrieve InputPane."); - } + m_keyboardRect = getInputPaneRect(inputPane, m_screen->scaleFactor()); + m_isInputPanelVisible = !m_keyboardRect.isEmpty(); + } else { + qWarning("failed to retrieve InputPane."); + } + return S_OK; + }); + connect(QGuiApplication::inputMethod(), &QInputMethod::cursorRectangleChanged, this, &QWinRTInputContext::updateScreenCursorRect); } -- cgit v1.2.3 From 251d6094abf423f96aa0f10921defb4c6a805d14 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 14 Sep 2016 14:15:28 +0200 Subject: Silence warning from syncqt Apparently syncqt considers anything like "" to be an include statement, even if it's in a comment. Yet, in fact, the comment was not entirely correct here. Change-Id: I7a661007ee86bb20242d54eb128c6b646cac15e7 Reviewed-by: Friedemann Kleint --- src/gui/kernel/qevent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 93374b2299..a062331bd8 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -52,7 +52,7 @@ #include #include // ### Qt 6: Remove #include -#include // ### Qt 6: Replace by and forward declare QFile +#include // ### Qt 6: Replace by and forward declare QFile #include #include // ### Qt 6: Replace by forward declaration -- cgit v1.2.3 From 6aa935cd92deb035739e8fea329ca2c4a435de54 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Thu, 18 Aug 2016 11:57:26 +0300 Subject: Use QString::fromLatin1() less to avoid string allocations QString::fromLatin1 always allocates memory, but there are cases where we can avoid/reduce allocations or/and reduce text size, e.g.: QStringBuilder expressions Fix: replace QString::fromLatin1 with QL1S QString::fromLatin1().arg(String) pattern Fix: replace with QStringBuilder Overloaded functions with QL1S arg Fix: replace QString::fromLatin1 with QL1S In rare cases if there is no overloaded function with QL1S and we have deal with string literal, replace QString::fromLatin1 with QStringLiteral. Change-Id: Iabe1a3cc0830f40ef78a0548afa4368583c31def Reviewed-by: Edward Welbourne --- src/corelib/mimetypes/qmimeprovider.cpp | 9 ++++----- src/dbus/qdbusinternalfilters.cpp | 6 ++---- src/gui/image/qimagereader.cpp | 2 +- src/gui/kernel/qkeysequence.cpp | 10 +++++++--- src/gui/text/qfontdatabase.cpp | 2 +- src/gui/text/qtextodfwriter.cpp | 2 +- src/network/access/qhttpnetworkconnection.cpp | 4 ++-- src/network/kernel/qnetworkinterface_unix.cpp | 2 +- src/network/kernel/qnetworkproxy_generic.cpp | 2 +- .../devicediscovery/qdevicediscovery_static.cpp | 2 +- src/plugins/platforms/haiku/qhaikuclipboard.cpp | 2 +- src/plugins/platforms/xcb/qxcbmime.cpp | 2 +- src/plugins/sqldrivers/db2/qsql_db2.cpp | 3 ++- src/printsupport/dialogs/qprintpreviewdialog.cpp | 2 +- src/widgets/accessible/qaccessiblewidgets.cpp | 2 +- src/widgets/kernel/qaction.cpp | 2 +- src/widgets/widgets/qlcdnumber.cpp | 4 ++-- src/widgets/widgets/qpushbutton.cpp | 2 +- 18 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp index e25eb4272d..a798d9eff6 100644 --- a/src/corelib/mimetypes/qmimeprovider.cpp +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -572,10 +572,9 @@ void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data) const QString file = data.name + QLatin1String(".xml"); // shared-mime-info since 1.3 lowercases the xml files - QStringList mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QString::fromLatin1("mime/") + file.toLower()); - if (mimeFiles.isEmpty()) { - mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QString::fromLatin1("mime/") + file); // pre-1.3 - } + QStringList mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/") + file.toLower()); + if (mimeFiles.isEmpty()) + mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/") + file); // pre-1.3 if (mimeFiles.isEmpty()) { qWarning() << "No file found for" << file << ", even though update-mime-info said it would exist.\n" "Either it was just removed, or the directory doesn't have executable permission..." @@ -807,7 +806,7 @@ bool QMimeXMLProvider::load(const QString &fileName, QString *errorMessage) QFile file(fileName); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { if (errorMessage) - *errorMessage = QString::fromLatin1("Cannot open %1: %2").arg(fileName, file.errorString()); + *errorMessage = QLatin1String("Cannot open ") + fileName + QLatin1String(": ") + file.errorString(); return false; } diff --git a/src/dbus/qdbusinternalfilters.cpp b/src/dbus/qdbusinternalfilters.cpp index ad6b06da23..03e04bb2f5 100644 --- a/src/dbus/qdbusinternalfilters.cpp +++ b/src/dbus/qdbusinternalfilters.cpp @@ -116,8 +116,7 @@ static QString generateSubObjectXml(QObject *object) for ( ; it != end; ++it) { QString name = (*it)->objectName(); if (!name.isEmpty() && QDBusUtil::isValidPartOfObjectPath(name)) - retval += QString::fromLatin1(" \n") - .arg(name); + retval += QLatin1String(" \n"); } return retval; } @@ -192,8 +191,7 @@ QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node node.children.constEnd(); for ( ; it != end; ++it) if (it->obj || !it->children.isEmpty()) - xml_data += QString::fromLatin1(" \n") - .arg(it->name); + xml_data += QLatin1String(" name + QLatin1String("\"/>\n"); } xml_data += QLatin1String("\n"); diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 0320d032b0..4390e46fde 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -569,7 +569,7 @@ bool QImageReaderPrivate::initHandler() do { file->setFileName(fileName + QLatin1Char('.') - + QString::fromLatin1(extensions.at(currentExtension++).constData())); + + QLatin1String(extensions.at(currentExtension++).constData())); file->open(QIODevice::ReadOnly); } while (!file->isOpen() && currentExtension < extensions.size()); diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 9a75f4bc83..d59bd63caf 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -1211,9 +1211,13 @@ QString QKeySequence::encodeString(int key) static inline void addKey(QString &str, const QString &theKey, QKeySequence::SequenceFormat format) { - if (!str.isEmpty()) - str += (format == QKeySequence::NativeText) ? QCoreApplication::translate("QShortcut", "+") - : QString::fromLatin1("+"); + if (!str.isEmpty()) { + if (format == QKeySequence::NativeText) + str += QCoreApplication::translate("QShortcut", "+"); + else + str += QLatin1Char('+'); + } + str += theKey; } diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index a3a3f20b18..7fcac9b9f2 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -2439,7 +2439,7 @@ int QFontDatabasePrivate::addAppFont(const QByteArray &fontData, const QString & } if (font.fileName.isEmpty() && !fontData.isEmpty()) - font.fileName = QString::fromLatin1(":qmemoryfonts/") + QString::number(i); + font.fileName = QLatin1String(":qmemoryfonts/") + QString::number(i); registerFont(&font); if (font.families.isEmpty()) diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index 73d2e545ba..e228b3c840 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE static QString pixelToPoint(qreal pixels) { // we hardcode 96 DPI, we do the same in the ODF importer to have a perfect roundtrip. - return QString::number(pixels * 72 / 96) + QString::fromLatin1("pt"); + return QString::number(pixels * 72 / 96) + QLatin1String("pt"); } // strategies diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 74fc23957c..8e5cfd9497 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -319,9 +319,9 @@ void QHttpNetworkConnectionPrivate::prepareRequest(HttpMessagePair &messagePair) if (systemLocale == QLatin1String("C")) acceptLanguage = QString::fromLatin1("en,*"); else if (systemLocale.startsWith(QLatin1String("en-"))) - acceptLanguage = QString::fromLatin1("%1,*").arg(systemLocale); + acceptLanguage = systemLocale + QLatin1String(",*"); else - acceptLanguage = QString::fromLatin1("%1,en,*").arg(systemLocale); + acceptLanguage = systemLocale + QLatin1String(",en,*"); request.setHeaderField("Accept-Language", acceptLanguage.toLatin1()); } diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp index da53ccfe70..2fa98c0e07 100644 --- a/src/network/kernel/qnetworkinterface_unix.cpp +++ b/src/network/kernel/qnetworkinterface_unix.cpp @@ -488,7 +488,7 @@ static QList interfaceListing() interfaces = createInterfaces(interfaceListing); for (ifaddrs *ptr = interfaceListing; ptr; ptr = ptr->ifa_next) { // Find the interface - QString name = QString::fromLatin1(ptr->ifa_name); + QLatin1String name(ptr->ifa_name); QNetworkInterfacePrivate *iface = 0; QList::Iterator if_it = interfaces.begin(); for ( ; if_it != interfaces.end(); ++if_it) diff --git a/src/network/kernel/qnetworkproxy_generic.cpp b/src/network/kernel/qnetworkproxy_generic.cpp index e69870a98c..3ff0cc5168 100644 --- a/src/network/kernel/qnetworkproxy_generic.cpp +++ b/src/network/kernel/qnetworkproxy_generic.cpp @@ -79,7 +79,7 @@ static bool ignoreProxyFor(const QNetworkProxyQuery &query) if (!peerHostName.startsWith('.')) peerHostName.prepend('.'); - if (peerHostName.endsWith(QString::fromLatin1(token))) + if (peerHostName.endsWith(QLatin1String(token))) return true; } diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp index 83a9343a6a..5c72dbe7e2 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp +++ b/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp @@ -135,7 +135,7 @@ bool QDeviceDiscoveryStatic::checkDeviceType(const QString &device) qCDebug(lcDD) << "doing static device discovery for " << device; - if ((m_types & Device_DRM) && device.contains(QString::fromLatin1(QT_DRM_DEVICE_PREFIX))) { + if ((m_types & Device_DRM) && device.contains(QLatin1String(QT_DRM_DEVICE_PREFIX))) { QT_CLOSE(fd); return true; } diff --git a/src/plugins/platforms/haiku/qhaikuclipboard.cpp b/src/plugins/platforms/haiku/qhaikuclipboard.cpp index 0194a0415a..774da4432a 100644 --- a/src/plugins/platforms/haiku/qhaikuclipboard.cpp +++ b/src/plugins/platforms/haiku/qhaikuclipboard.cpp @@ -91,7 +91,7 @@ QMimeData *QHaikuClipboard::mimeData(QClipboard::Mode mode) const status_t status = clipboard->FindData(name, B_MIME_TYPE, &data, &dataLen); if (dataLen && (status == B_OK)) { - const QString format = QString::fromLatin1(name); + const QLatin1String format(name); if (format == QLatin1String("text/plain")) { m_systemMimeData->setText(QString::fromLocal8Bit(reinterpret_cast(data), dataLen)); } else if (format == QLatin1String("text/html")) { diff --git a/src/plugins/platforms/xcb/qxcbmime.cpp b/src/plugins/platforms/xcb/qxcbmime.cpp index 749906d1e8..f71c5464d0 100644 --- a/src/plugins/platforms/xcb/qxcbmime.cpp +++ b/src/plugins/platforms/xcb/qxcbmime.cpp @@ -173,7 +173,7 @@ QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, // qDebug() << "mimeConvertDataToFormat" << format << atomName << data; if (!encoding.isEmpty() - && atomName == format + QLatin1String(";charset=") + QString::fromLatin1(encoding)) { + && atomName == format + QLatin1String(";charset=") + QLatin1String(encoding)) { #ifndef QT_NO_TEXTCODEC if (requestedType == QVariant::String) { diff --git a/src/plugins/sqldrivers/db2/qsql_db2.cpp b/src/plugins/sqldrivers/db2/qsql_db2.cpp index 4ccc3aca9e..9408f464e0 100644 --- a/src/plugins/sqldrivers/db2/qsql_db2.cpp +++ b/src/plugins/sqldrivers/db2/qsql_db2.cpp @@ -1665,7 +1665,8 @@ QString QDB2Driver::formatValue(const QSqlField &field, bool trimStrings) const } case QVariant::ByteArray: { QByteArray ba = field.value().toByteArray(); - QString res = QString::fromLatin1("BLOB(X'"); + QString res; + res += QLatin1String("BLOB(X'"); static const char hexchars[] = "0123456789abcdef"; for (int i = 0; i < ba.size(); ++i) { uchar s = (uchar) ba[i]; diff --git a/src/printsupport/dialogs/qprintpreviewdialog.cpp b/src/printsupport/dialogs/qprintpreviewdialog.cpp index 435f8869c4..c996e0d556 100644 --- a/src/printsupport/dialogs/qprintpreviewdialog.cpp +++ b/src/printsupport/dialogs/qprintpreviewdialog.cpp @@ -334,7 +334,7 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer) QString caption = QCoreApplication::translate("QPrintPreviewDialog", "Print Preview"); if (!printer->docName().isEmpty()) - caption += QString::fromLatin1(": ") + printer->docName(); + caption += QLatin1String(": ") + printer->docName(); q->setWindowTitle(caption); if (!printer->isValid() diff --git a/src/widgets/accessible/qaccessiblewidgets.cpp b/src/widgets/accessible/qaccessiblewidgets.cpp index 95888924fb..b814762168 100644 --- a/src/widgets/accessible/qaccessiblewidgets.cpp +++ b/src/widgets/accessible/qaccessiblewidgets.cpp @@ -830,7 +830,7 @@ QString QAccessibleTextWidget::attributes(int offset, int *startOffset, int *end family = family.replace('=', QLatin1String("\\=")); family = family.replace(';', QLatin1String("\\;")); family = family.replace('\"', QLatin1String("\\\"")); - attrs["font-family"] = QString::fromLatin1("\"%1\"").arg(family); + attrs["font-family"] = QLatin1Char('"') + family + QLatin1Char('"'); } int fontSize = int(charFormatFont.pointSize()); diff --git a/src/widgets/kernel/qaction.cpp b/src/widgets/kernel/qaction.cpp index 72aae647e0..e0700d877e 100644 --- a/src/widgets/kernel/qaction.cpp +++ b/src/widgets/kernel/qaction.cpp @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE */ static QString qt_strippedText(QString s) { - s.remove( QString::fromLatin1("...") ); + s.remove(QStringLiteral("...")); for (int i = 0; i < s.size(); ++i) { if (s.at(i) == QLatin1Char('&')) s.remove(i, 1); diff --git a/src/widgets/widgets/qlcdnumber.cpp b/src/widgets/widgets/qlcdnumber.cpp index 2703e5d8a3..aa052ef5cb 100644 --- a/src/widgets/widgets/qlcdnumber.cpp +++ b/src/widgets/widgets/qlcdnumber.cpp @@ -188,8 +188,8 @@ static QString int2string(int num, int base, int ndigits, bool *oflow) } while (n != 0); len = ndigits - len; if (len > 0) - s.fill(QLatin1Char(' '), len); - s += QString::fromLatin1(p); + s += QString(len, QLatin1Char(' ')); + s += QLatin1String(p); } break; } diff --git a/src/widgets/widgets/qpushbutton.cpp b/src/widgets/widgets/qpushbutton.cpp index 5608a4aff9..bf10b9fb75 100644 --- a/src/widgets/widgets/qpushbutton.cpp +++ b/src/widgets/widgets/qpushbutton.cpp @@ -415,7 +415,7 @@ QSize QPushButton::sizeHint() const QString s(text()); bool empty = s.isEmpty(); if (empty) - s = QString::fromLatin1("XXXX"); + s = QStringLiteral("XXXX"); QFontMetrics fm = fontMetrics(); QSize sz = fm.size(Qt::TextShowMnemonic, s); if(!empty || !w) -- cgit v1.2.3 From 4ac150682ab77cd4e2de9b1b01dbd725465ea8c1 Mon Sep 17 00:00:00 2001 From: Sune Vuorela Date: Tue, 13 Sep 2016 19:47:00 +0200 Subject: API Review: Don't reorder existing enum values Inserting things into the middle of an enum breaks backwards compatibility, so don't do that. Change-Id: Ie8e2768e8681f0237e7f233f4461f884b4b1b4f9 Reviewed-by: Richard J. Moore Reviewed-by: Edward Welbourne --- src/network/access/qnetworkrequest.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h index 00375f285c..ad8f5bddd9 100644 --- a/src/network/access/qnetworkrequest.h +++ b/src/network/access/qnetworkrequest.h @@ -87,10 +87,10 @@ public: BackgroundRequestAttribute, SpdyAllowedAttribute, SpdyWasUsedAttribute, - HTTP2AllowedAttribute, - HTTP2WasUsedAttribute, EmitAllUploadProgressSignalsAttribute, FollowRedirectsAttribute, + HTTP2AllowedAttribute, + HTTP2WasUsedAttribute, User = 1000, UserMax = 32767 -- cgit v1.2.3 From ec770a85305c40ba182bdc67dddcf412facbfb74 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 13 Sep 2016 15:00:50 -0700 Subject: Nitpick: fix style in QtCore code added since 5.7 Change-Id: I9093948278414644a416fffd147400f99fc9f844 Reviewed-by: Marc Mutz Reviewed-by: Anton Kudryavtsev --- src/corelib/tools/qstring.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index a110c129de..53a28d9278 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -1440,7 +1440,8 @@ public: QStringRef mid(int pos, int n = -1) const Q_REQUIRED_RESULT; void truncate(int pos) Q_DECL_NOTHROW { m_size = qBound(0, pos, m_size); } - void chop(int n) Q_DECL_NOTHROW { + void chop(int n) Q_DECL_NOTHROW + { if (n >= m_size) m_size = 0; else if (n > 0) -- cgit v1.2.3 From b630a4513c3023d0217c53638841bd06d1deda42 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 6 Jun 2016 06:30:41 -0500 Subject: QtConcurrent: use QDeadlineTimer to get the clock tick Instead of duplicating what QElapsedTimer & QDeadlineTimer already do. Well, technically speaking, we aren't getting ticks, but nanoseconds now, but the times are only used in comparisons with each other, to measure the control overhead, so the unit in which they are measured doesn't matter. This also makes all OSes use the same type of timers. There's no exception for per-thread timing. Change-Id: I115db302eb114bed8cd1fffd14557b228284f2c0 Reviewed-by: Marc Mutz --- src/concurrent/concurrent.pro | 4 -- src/concurrent/qtconcurrentiteratekernel.cpp | 75 +--------------------------- 2 files changed, 2 insertions(+), 77 deletions(-) diff --git a/src/concurrent/concurrent.pro b/src/concurrent/concurrent.pro index 337f4042bd..017153c74d 100644 --- a/src/concurrent/concurrent.pro +++ b/src/concurrent/concurrent.pro @@ -37,8 +37,4 @@ HEADERS += \ # private headers HEADERS += \ -qtConfig(clock-gettime) { - linux-*|hpux-*|solaris-*: LIBS_PRIVATE *= -lrt -} - load(qt_module) diff --git a/src/concurrent/qtconcurrentiteratekernel.cpp b/src/concurrent/qtconcurrentiteratekernel.cpp index 4b6ccc2810..52218f794b 100644 --- a/src/concurrent/qtconcurrentiteratekernel.cpp +++ b/src/concurrent/qtconcurrentiteratekernel.cpp @@ -39,20 +39,7 @@ #include "qtconcurrentiteratekernel.h" -#if defined(Q_OS_MAC) -#include -#include -#include -#elif defined(Q_OS_UNIX) -#if defined(Q_OS_HURD) -#include -#endif -#include -#include -#elif defined(Q_OS_WIN) -#include -#endif - +#include #include "private/qfunctions_p.h" @@ -65,69 +52,11 @@ enum { MedianSize = 7 }; -#if defined(Q_OS_MAC) - static qint64 getticks() { - return mach_absolute_time(); + return QDeadlineTimer::current(Qt::PreciseTimer).deadlineNSecs(); } -#elif defined(Q_OS_UNIX) - - -static qint64 getticks() -{ -#if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)) || defined(Q_OS_OPENBSD) - clockid_t clockId; - -#ifndef _POSIX_THREAD_CPUTIME - clockId = CLOCK_REALTIME; -#elif (_POSIX_THREAD_CPUTIME-0 <= 0) - // if we don't have CLOCK_THREAD_CPUTIME_ID, we have to just use elapsed realtime instead - clockId = CLOCK_REALTIME; - -# if (_POSIX_THREAD_CPUTIME-0 == 0) - // detect availablility of CLOCK_THREAD_CPUTIME_ID - static QBasicAtomicInt sUseThreadCpuTime = Q_BASIC_ATOMIC_INITIALIZER(-2); - int useThreadCpuTime = sUseThreadCpuTime.load(); - if (useThreadCpuTime == -2) { - // sysconf() will return either -1L or _POSIX_VERSION - // (don't care about sysconf's exact return value) - useThreadCpuTime = sysconf(_SC_THREAD_CPUTIME) == -1L ? -1 : 0 ; - sUseThreadCpuTime.store(useThreadCpuTime); // might happen multiple times, but doesn't matter - } - if (useThreadCpuTime != -1) - clockId = CLOCK_THREAD_CPUTIME_ID; -# endif -#else - clockId = CLOCK_THREAD_CPUTIME_ID; -#endif - - struct timespec ts; - if (clock_gettime(clockId, &ts) == -1) - return 0; - return (ts.tv_sec * 1000000000) + ts.tv_nsec; -#else - - // no clock_gettime(), fall back to wall time - struct timeval tv; - gettimeofday(&tv, 0); - return (tv.tv_sec * 1000000) + tv.tv_usec; -#endif -} - -#elif defined(Q_OS_WIN) - -static qint64 getticks() -{ - LARGE_INTEGER x; - if (!QueryPerformanceCounter(&x)) - return 0; - return x.QuadPart; -} - -#endif - static double elapsed(qint64 after, qint64 before) { return double(after - before); -- cgit v1.2.3 From 60e8714e58369fd786707847575ba842f08530f1 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 14 Sep 2016 08:26:50 +0200 Subject: Bring back QSysInfo enumeration values for Windows CE Partially revert 7fc2864dc5391096a19c2d5f80695129c24cc303. Entries should be kept until Qt 6 for source compatibility. Task-number: QTBUG-55973 Change-Id: I09346fcd9227224f878f5ee064152e85f075ae09 Reviewed-by: Maurice Kalinowski Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.cpp | 6 ++++++ src/corelib/global/qsysinfo.h | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 5687920c9b..a9a583d808 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1172,6 +1172,12 @@ bool qSharedBuild() Q_DECL_NOTHROW \value WV_None Operating system other than Windows. + \omitvalue WV_CE + \omitvalue WV_CENET + \omitvalue WV_CE_5 + \omitvalue WV_CE_6 + \omitvalue WV_CE_based + \sa MacVersion */ diff --git a/src/corelib/global/qsysinfo.h b/src/corelib/global/qsysinfo.h index f01b45cbf9..23f412aa6a 100644 --- a/src/corelib/global/qsysinfo.h +++ b/src/corelib/global/qsysinfo.h @@ -109,7 +109,13 @@ public: WV_6_1 = WV_WINDOWS7, WV_6_2 = WV_WINDOWS8, WV_6_3 = WV_WINDOWS8_1, - WV_10_0 = WV_WINDOWS10 + WV_10_0 = WV_WINDOWS10, + + WV_CE = 0x0100, + WV_CENET = 0x0200, + WV_CE_5 = 0x0300, + WV_CE_6 = 0x0400, + WV_CE_based = 0x0f00 }; #if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN) static const WinVersion WindowsVersion; -- cgit v1.2.3 From 001efe14f2a0af25d10179fd6c06e4a7113ec83d Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 17 Aug 2016 14:27:36 +0200 Subject: DirectWrite: Fix embedding fonts in PDF If no filename is stored in the faceId() of the font engine, then the PDF engine will bail out and embed each glyph separately instead of embedding the font. This would cause PDFs to be huge and unsearchable when high-dpi was active, since we will automatically default to the DirectWrite engine in this case. [ChangeLog][QtGui][Windows] Fixed embedding fonts in PDF when dpi scaling is active or when the hinting preference was none or vertical hinting. Task-number: QTBUG-54740 Change-Id: I20630595f51660109c5a12c52076738a04036520 Reviewed-by: Friedemann Kleint Reviewed-by: Simon Hausmann Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../windows/qwindowsfontenginedirectwrite.cpp | 89 ++++++++++++++++++++++ .../windows/qwindowsfontenginedirectwrite.h | 3 + 2 files changed, 92 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index 39a4eb81ca..ec73a4c065 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -236,6 +237,82 @@ QWindowsFontEngineDirectWrite::~QWindowsFontEngineDirectWrite() m_directWriteBitmapRenderTarget->Release(); } +#ifndef Q_CC_MINGW +typedef IDWriteLocalFontFileLoader QIdWriteLocalFontFileLoader; + +static UUID uuidIdWriteLocalFontFileLoader() +{ + return __uuidof(IDWriteLocalFontFileLoader); +} +#else // !Q_CC_MINGW +DECLARE_INTERFACE_(QIdWriteLocalFontFileLoader, IDWriteFontFileLoader) +{ + STDMETHOD(GetFilePathLengthFromKey)(THIS_ void const *, UINT32, UINT32*) PURE; + STDMETHOD(GetFilePathFromKey)(THIS_ void const *, UINT32, WCHAR *, UINT32) PURE; + STDMETHOD(GetLastWriteTimeFromKey)(THIS_ void const *, UINT32, FILETIME *) PURE; +}; + +static UUID uuidIdWriteLocalFontFileLoader() +{ + static const UUID result = { 0xb2d9f3ec, 0xc9fe, 0x4a11, {0xa2, 0xec, 0xd8, 0x62, 0x8, 0xf7, 0xc0, 0xa2}}; + return result; +} +#endif // Q_CC_MINGW + +QString QWindowsFontEngineDirectWrite::filenameFromFontFile(IDWriteFontFile *fontFile) +{ + IDWriteFontFileLoader *loader = Q_NULLPTR; + + HRESULT hr = fontFile->GetLoader(&loader); + if (FAILED(hr)) { + qErrnoWarning("%s: GetLoader failed", __FUNCTION__); + return QString(); + } + + QIdWriteLocalFontFileLoader *localLoader = Q_NULLPTR; + hr = loader->QueryInterface(uuidIdWriteLocalFontFileLoader(), + reinterpret_cast(&localLoader)); + + const void *fontFileReferenceKey = Q_NULLPTR; + UINT32 fontFileReferenceKeySize = 0; + if (SUCCEEDED(hr)) { + hr = fontFile->GetReferenceKey(&fontFileReferenceKey, + &fontFileReferenceKeySize); + if (FAILED(hr)) + qErrnoWarning(hr, "%s: GetReferenceKey failed", __FUNCTION__); + } + + UINT32 filePathLength = 0; + if (SUCCEEDED(hr)) { + hr = localLoader->GetFilePathLengthFromKey(fontFileReferenceKey, + fontFileReferenceKeySize, + &filePathLength); + if (FAILED(hr)) + qErrnoWarning(hr, "GetFilePathLength failed", __FUNCTION__); + } + + QString ret; + if (SUCCEEDED(hr) && filePathLength > 0) { + QVarLengthArray filePath(filePathLength + 1); + + hr = localLoader->GetFilePathFromKey(fontFileReferenceKey, + fontFileReferenceKeySize, + filePath.data(), + filePathLength + 1); + if (FAILED(hr)) + qErrnoWarning(hr, "%s: GetFilePathFromKey failed", __FUNCTION__); + else + ret = QString::fromWCharArray(filePath.data()); + } + + if (localLoader != Q_NULLPTR) + localLoader->Release(); + + if (loader != Q_NULLPTR) + loader->Release(); + return ret; +} + void QWindowsFontEngineDirectWrite::collectMetrics() { DWRITE_FONT_METRICS metrics; @@ -250,6 +327,13 @@ void QWindowsFontEngineDirectWrite::collectMetrics() m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight); m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap); m_underlinePosition = DESIGN_TO_LOGICAL(metrics.underlinePosition); + + IDWriteFontFile *fontFile = Q_NULLPTR; + UINT32 numberOfFiles = 1; + if (SUCCEEDED(m_directWriteFontFace->GetFiles(&numberOfFiles, &fontFile))) { + m_faceId.filename = QFile::encodeName(filenameFromFontFile(fontFile)); + fontFile->Release(); + } } QFixed QWindowsFontEngineDirectWrite::underlinePosition() const @@ -351,6 +435,11 @@ bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGly return true; } +QFontEngine::FaceId QWindowsFontEngineDirectWrite::faceId() const +{ + return m_faceId; +} + void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const { QVarLengthArray glyphIndices(glyphs->numGlyphs); diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h index fb2df00b7e..1978304b13 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h @@ -49,6 +49,7 @@ struct IDWriteFont; struct IDWriteFontFace; +struct IDWriteFontFile; struct IDWriteFactory; struct IDWriteBitmapRenderTarget; struct IDWriteGdiInterop; @@ -92,6 +93,7 @@ public: QFixed leading() const Q_DECL_OVERRIDE; QFixed xHeight() const Q_DECL_OVERRIDE; qreal maxCharWidth() const Q_DECL_OVERRIDE; + FaceId faceId() const Q_DECL_OVERRIDE; bool supportsSubPixelPositions() const Q_DECL_OVERRIDE; @@ -113,6 +115,7 @@ private: QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform); void collectMetrics(); void renderGlyphRun(QImage *destination, float r, float g, float b, float a, IDWriteGlyphRunAnalysis *glyphAnalysis, const QRect &boundingRect); + static QString filenameFromFontFile(IDWriteFontFile *fontFile); const QSharedPointer m_fontEngineData; -- cgit v1.2.3 From 97710f429fb06914b5cb86fdd3aa333eb8a90dff Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Sat, 10 Sep 2016 14:23:39 +0200 Subject: moc: Fix asserts on moc on empty token preceding ## operator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Regression introduced in c32ef0a725c7ac9d8a9ab053407389ef2fddc64e The expansion vector can be empty, in that case it is not allowed to call constLast() Task-number: QTBUG-55853 Change-Id: I47aa8eb7507ee91662215df42b4a66eebaa32bb5 Reviewed-by: Jędrzej Nowacki --- src/tools/moc/preprocessor.cpp | 6 +++--- tests/auto/tools/moc/parse-defines.h | 3 +++ tests/auto/tools/moc/tst_moc.cpp | 3 +++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index 5ce28d931b..11bf8d7937 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -696,9 +696,9 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym next = arg.at(0); } - Symbol last = expansion.constLast(); - if (!expansion.isEmpty() && last.token == s.token && last.token != STRING_LITERAL) { - expansion.pop_back(); + if (!expansion.isEmpty() && expansion.constLast().token == s.token + && expansion.constLast().token != STRING_LITERAL) { + Symbol last = expansion.takeLast(); QByteArray lexem = last.lexem() + next.lexem(); expansion += Symbol(lineNum, last.token, lexem); diff --git a/tests/auto/tools/moc/parse-defines.h b/tests/auto/tools/moc/parse-defines.h index 9fb5da4b07..6100bf67ad 100644 --- a/tests/auto/tools/moc/parse-defines.h +++ b/tests/auto/tools/moc/parse-defines.h @@ -139,6 +139,9 @@ public slots: signals: DEFINE_CMDLINE_SIGNAL; +#define QTBUG55853(X) PD_DEFINE1(X, signalQTBUG55853) +#define PD_EMPTY /* empty */ + void QTBUG55853(PD_EMPTY)(); }; #undef QString diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index a3648c95b6..601b1bb36b 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -3397,6 +3397,9 @@ void tst_Moc::parseDefines() index = mo->indexOfSignal("cmdlineSignal(QMap)"); QVERIFY(index != -1); + + index = mo->indexOfSignal("signalQTBUG55853()"); + QVERIFY(index != -1); } void tst_Moc::preprocessorOnly() -- cgit v1.2.3 From ee17289dc97ccac865ab31e4c48c99587feab6cd Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 16 Sep 2016 09:55:50 +0200 Subject: Fix out of source builds on windows Change-Id: If4d03e889dda3cf7557c3d41dda4ffad8790f2e0 Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll --- src/3rdparty/freetype/freetype.pro | 2 +- src/angle/src/compiler/preprocessor/preprocessor.pro | 2 +- src/angle/src/compiler/translator.pro | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/3rdparty/freetype/freetype.pro b/src/3rdparty/freetype/freetype.pro index 1e12dadc5d..6d630d4190 100644 --- a/src/3rdparty/freetype/freetype.pro +++ b/src/3rdparty/freetype/freetype.pro @@ -69,7 +69,7 @@ DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB include(../zlib_dependency.pri) QT_FOR_CONFIG += gui-private -include(../../gui/qtgui-config.pri) +include($$OUT_PWD/../../gui/qtgui-config.pri) DEFINES += FT_CONFIG_OPTION_USE_PNG include($$PWD/../png_dependency.pri) diff --git a/src/angle/src/compiler/preprocessor/preprocessor.pro b/src/angle/src/compiler/preprocessor/preprocessor.pro index c13cf7ba8d..9d0728a72d 100644 --- a/src/angle/src/compiler/preprocessor/preprocessor.pro +++ b/src/angle/src/compiler/preprocessor/preprocessor.pro @@ -1,5 +1,5 @@ CONFIG += static -include(../../../../gui/qtgui-config.pri) +include($$OUT_PWD/../../../../gui/qtgui-config.pri) qtConfig(dynamicgl): CONFIG += not_installed include(../../config.pri) diff --git a/src/angle/src/compiler/translator.pro b/src/angle/src/compiler/translator.pro index 4c0a05e45c..2e5adaee96 100644 --- a/src/angle/src/compiler/translator.pro +++ b/src/angle/src/compiler/translator.pro @@ -1,5 +1,5 @@ CONFIG += static -include(../../../gui/qtgui-config.pri) +include($$OUT_PWD/../../../gui/qtgui-config.pri) qtConfig(dynamicgl): CONFIG += not_installed include(../config.pri) -- cgit v1.2.3 From fdca8cb09ee330813c41fd1bd20b2795a0a30e04 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 6 Sep 2016 13:21:06 +0200 Subject: HTTP/2 tests: Remove execute permissions from source files Source (.cpp and .h) files should not be executable. Change-Id: I021d8733185d73d071fcaf3df7e529862a490b63 Reviewed-by: Timur Pocheptsov --- tests/auto/network/access/http2/http2srv.cpp | 0 tests/auto/network/access/http2/http2srv.h | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 tests/auto/network/access/http2/http2srv.cpp mode change 100755 => 100644 tests/auto/network/access/http2/http2srv.h diff --git a/tests/auto/network/access/http2/http2srv.cpp b/tests/auto/network/access/http2/http2srv.cpp old mode 100755 new mode 100644 diff --git a/tests/auto/network/access/http2/http2srv.h b/tests/auto/network/access/http2/http2srv.h old mode 100755 new mode 100644 -- cgit v1.2.3 From 31a63b69037c680101bf82a7161d4a0e5184dd86 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 7 Sep 2016 16:55:51 +0300 Subject: Say hello to Android 6+ permissions model This API was introduced by Android v23 and is used in connection with the new permission request system. From Android v23 onwards, some permissions such as Location permissions cannot only be granted via Android's Manifest files. An additional runtime check/request system was introduced which forces applications to prompt the user the first time a privileged function is called. Such user prompt responses are returned to the current application via the Activity.onRequestPermissionsResult(..) callback. This change add Qt API to nicely check & request permissions. For now this is private API which can be used to fix permission problems in other Qt compontents. Later Qt versions will introduce a public API to QtAndroidExtras. [ChangeLog][QtCore][Android] Introduced a mechanism to forward permission related callbacks on Activity objects to interested parties. Task-number: QTBUG-55035 Task-number: QTBUG-50759 Change-Id: I64ee748d741b39e35c4713ed9fdd15dd1d96dc56 Reviewed-by: Christian Stromme Reviewed-by: Alex Blasche --- .../qtproject/qt5/android/QtActivityDelegate.java | 5 + .../src/org/qtproject/qt5/android/QtNative.java | 19 +++- .../qtproject/qt5/android/bindings/QtActivity.java | 7 ++ .../qt5/android/bindings/QtApplication.java | 1 + src/corelib/kernel/qjnihelpers.cpp | 122 ++++++++++++++++++++- src/corelib/kernel/qjnihelpers_p.h | 11 ++ 6 files changed, 158 insertions(+), 7 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index b602cabd27..bfdbaed43f 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -1455,4 +1455,9 @@ public class QtActivityDelegate } return false; } + + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) + { + QtNative.sendRequestPermissionsResult(requestCode, permissions, grantResults); + } } diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index 4df2cb88c9..6876aac11f 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -455,20 +455,25 @@ public class QtNative } } - public static int checkSelfPermission(final String permission) + public static Context getContext() { + if (m_activity == null) + return m_activity; + return m_service; + } + + public static int checkSelfPermission(String permission) { int perm = PackageManager.PERMISSION_DENIED; synchronized (m_mainActivityMutex) { - if (m_activity == null) - return perm; + Context context = getContext(); try { if (Build.VERSION.SDK_INT >= 23) { if (m_checkSelfPermissionMethod == null) m_checkSelfPermissionMethod = Context.class.getMethod("checkSelfPermission", String.class); - perm = (Integer)m_checkSelfPermissionMethod.invoke(m_activity, permission); + perm = (Integer)m_checkSelfPermissionMethod.invoke(context, permission); } else { - final PackageManager pm = m_activity.getPackageManager(); - perm = pm.checkPermission(permission, m_activity.getPackageName()); + final PackageManager pm = context.getPackageManager(); + perm = pm.checkPermission(permission, context.getApplicationContext().getPackageName()); } } catch (Exception e) { e.printStackTrace(); @@ -831,6 +836,8 @@ public class QtNative public static native void runPendingCppRunnables(); + public static native void sendRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults); + private static native void setNativeActivity(Activity activity); private static native void setNativeService(Service service); } diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java index 573a28e44b..22ff1738c8 100644 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java +++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java @@ -981,4 +981,11 @@ public class QtActivity extends Activity //--------------------------------------------------------------------------- //@ANDROID-12 + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) + { + if (QtApplication.m_delegateObject != null && QtApplication.onRequestPermissionsResult != null) { + QtApplication.invokeDelegateMethod(QtApplication.onRequestPermissionsResult, requestCode , permissions, grantResults); + return; + } + } } diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtApplication.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtApplication.java index 1078060d7f..afc0432bdd 100644 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtApplication.java +++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtApplication.java @@ -64,6 +64,7 @@ public class QtApplication extends Application public static Method onKeyShortcut = null; public static Method dispatchGenericMotionEvent = null; public static Method onGenericMotionEvent = null; + public static Method onRequestPermissionsResult = null; private static String activityClassName; public static void setQtContextDelegate(Class clazz, Object listener) { diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp index 102b835089..6a46f7dd11 100644 --- a/src/corelib/kernel/qjnihelpers.cpp +++ b/src/corelib/kernel/qjnihelpers.cpp @@ -38,14 +38,17 @@ ****************************************************************************/ #include "qjnihelpers_p.h" +#include "qjni_p.h" #include "qmutex.h" #include "qlist.h" #include "qsemaphore.h" #include "qsharedpointer.h" #include "qvector.h" +#include "qthread.h" #include #include +#include QT_BEGIN_NAMESPACE @@ -60,6 +63,22 @@ static jmethodID g_hideSplashScreenMethodID = Q_NULLPTR; Q_GLOBAL_STATIC(std::deque, g_pendingRunnables); Q_GLOBAL_STATIC(QMutex, g_pendingRunnablesMutex); +class PermissionsResultClass : public QObject +{ + Q_OBJECT +public: + PermissionsResultClass(const QtAndroidPrivate::PermissionsResultFunc &func) : m_func(func) {} + Q_INVOKABLE void sendResult(const QtAndroidPrivate::PermissionsHash &result) { m_func(result); } + +private: + QtAndroidPrivate::PermissionsResultFunc m_func; +}; + +typedef QHash> PendingPermissionRequestsHash; +Q_GLOBAL_STATIC(PendingPermissionRequestsHash, g_pendingPermissionRequests); +Q_GLOBAL_STATIC(QMutex, g_pendingPermissionRequestsMutex); +Q_GLOBAL_STATIC(QAtomicInt, g_requestPermissionsRequestCode); + // function called from Java from Android UI thread static void runPendingCppRunnables(JNIEnv */*env*/, jobject /*obj*/) { @@ -81,9 +100,43 @@ namespace { QMutex mutex; QVector listeners; }; + + enum { + PERMISSION_GRANTED = 0 + }; } Q_GLOBAL_STATIC(GenericMotionEventListeners, g_genericMotionEventListeners) +static void sendRequestPermissionsResult(JNIEnv *env, jobject /*obj*/, jint requestCode, + jobjectArray permissions, jintArray grantResults) +{ + g_pendingPermissionRequestsMutex->lock(); + auto it = g_pendingPermissionRequests->find(requestCode); + if (it == g_pendingPermissionRequests->end()) { + g_pendingPermissionRequestsMutex->unlock(); + // show an error or something ? + return; + } + g_pendingPermissionRequestsMutex->unlock(); + + Qt::ConnectionType connection = QThread::currentThread() == it.value()->thread() ? Qt::DirectConnection : Qt::BlockingQueuedConnection; + QtAndroidPrivate::PermissionsHash hash; + const int size = env->GetArrayLength(permissions); + std::unique_ptr results(new jint[size]); + env->GetIntArrayRegion(grantResults, 0, size, results.get()); + for (int i = 0 ; i < size; ++i) { + const auto &permission = QJNIObjectPrivate(env->GetObjectArrayElement(permissions, i)).toString(); + auto value = results[i] == PERMISSION_GRANTED ? + QtAndroidPrivate::PermissionsResult::Granted : + QtAndroidPrivate::PermissionsResult::Denied; + hash[permission] = value; + } + QMetaObject::invokeMethod(it.value().data(), "sendResult", connection, Q_ARG(QtAndroidPrivate::PermissionsHash, hash)); + g_pendingPermissionRequestsMutex->lock(); + g_pendingPermissionRequests->erase(it); + g_pendingPermissionRequestsMutex->unlock(); +} + static jboolean dispatchGenericMotionEvent(JNIEnv *, jclass, jobject event) { jboolean ret = JNI_FALSE; @@ -328,7 +381,8 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env) {"dispatchGenericMotionEvent", "(Landroid/view/MotionEvent;)Z", reinterpret_cast(dispatchGenericMotionEvent)}, {"dispatchKeyEvent", "(Landroid/view/KeyEvent;)Z", reinterpret_cast(dispatchKeyEvent)}, {"setNativeActivity", "(Landroid/app/Activity;)V", reinterpret_cast(setNativeActivity)}, - {"setNativeService", "(Landroid/app/Service;)V", reinterpret_cast(setNativeService)} + {"setNativeService", "(Landroid/app/Service;)V", reinterpret_cast(setNativeService)}, + {"sendRequestPermissionsResult", "(I[Ljava/lang/String;[I)V", reinterpret_cast(sendRequestPermissionsResult)}, }; const bool regOk = (env->RegisterNatives(jQtNative, methods, sizeof(methods) / sizeof(methods[0])) == JNI_OK); @@ -411,6 +465,70 @@ void QtAndroidPrivate::runOnAndroidThreadSync(const QtAndroidPrivate::Runnable & sem->tryAcquire(1, timeoutMs); } +void QtAndroidPrivate::requestPermissions(JNIEnv *env, const QStringList &permissions, const QtAndroidPrivate::PermissionsResultFunc &callbackFunc, bool directCall) +{ + if (androidSdkVersion() < 23 || !activity()) { + QHash res; + for (const auto &perm : permissions) + res[perm] = checkPermission(perm); + callbackFunc(res); + return; + } + // Check API 23+ permissions + const int requestCode = (*g_requestPermissionsRequestCode)++; + if (!directCall) { + g_pendingPermissionRequestsMutex->lock(); + (*g_pendingPermissionRequests)[requestCode] = QSharedPointer::create(callbackFunc); + g_pendingPermissionRequestsMutex->unlock(); + } + + runOnAndroidThread([permissions, callbackFunc, requestCode, directCall] { + if (directCall) { + g_pendingPermissionRequestsMutex->lock(); + (*g_pendingPermissionRequests)[requestCode] = QSharedPointer::create(callbackFunc); + g_pendingPermissionRequestsMutex->unlock(); + } + + QJNIEnvironmentPrivate env; + auto array = env->NewObjectArray(permissions.size(), env->FindClass("java/lang/String"), nullptr); + int index = 0; + for (const auto &perm : permissions) + env->SetObjectArrayElement(array, index++, QJNIObjectPrivate::fromString(perm).object()); + QJNIObjectPrivate(activity()).callMethod("requestPermissions", "([Ljava/lang/String;I)V", array, requestCode); + env->DeleteLocalRef(array); + }, env); +} + +QHash QtAndroidPrivate::requestPermissionsSync(JNIEnv *env, const QStringList &permissions, int timeoutMs) +{ + QSharedPointer> res(new QHash()); + QSharedPointer sem(new QSemaphore); + requestPermissions(env, permissions, [sem, res](const QHash &result){ + *res = result; + sem->release(); + }, true); + sem->tryAcquire(1, timeoutMs); + return *res; +} + +QtAndroidPrivate::PermissionsResult QtAndroidPrivate::checkPermission(const QString &permission) +{ + const auto res = QJNIObjectPrivate::callStaticMethod("org/qtproject/qt5/android/QtNative", + "checkSelfPermission", + "(Ljava/lang/String;)I", + QJNIObjectPrivate::fromString(permission).object()); + return res == PERMISSION_GRANTED ? PermissionsResult::Granted : PermissionsResult::Denied; +} + +bool QtAndroidPrivate::shouldShowRequestPermissionRationale(const QString &permission) +{ + if (androidSdkVersion() < 23 || !activity()) + return false; + + return QJNIObjectPrivate(activity()).callMethod("shouldShowRequestPermissionRationale", "(Ljava/lang/String;)Z", + QJNIObjectPrivate::fromString(permission).object()); +} + void QtAndroidPrivate::registerGenericMotionEventListener(QtAndroidPrivate::GenericMotionEventListener *listener) { QMutexLocker locker(&g_genericMotionEventListeners()->mutex); @@ -441,3 +559,5 @@ void QtAndroidPrivate::hideSplashScreen(JNIEnv *env) } QT_END_NAMESPACE + +#include "qjnihelpers.moc" diff --git a/src/corelib/kernel/qjnihelpers_p.h b/src/corelib/kernel/qjnihelpers_p.h index 43e2f3af20..478f62a5c7 100644 --- a/src/corelib/kernel/qjnihelpers_p.h +++ b/src/corelib/kernel/qjnihelpers_p.h @@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE class QRunnable; +class QStringList; namespace QtAndroidPrivate { @@ -97,7 +98,13 @@ namespace QtAndroidPrivate virtual bool handleKeyEvent(jobject event) = 0; }; + enum class PermissionsResult { + Granted, + Denied + }; + typedef QHash PermissionsHash; typedef std::function Runnable; + typedef std::function PermissionsResultFunc; Q_CORE_EXPORT jobject activity(); Q_CORE_EXPORT jobject service(); @@ -109,6 +116,10 @@ namespace QtAndroidPrivate Q_CORE_EXPORT void runOnAndroidThread(const Runnable &runnable, JNIEnv *env); Q_CORE_EXPORT void runOnAndroidThreadSync(const Runnable &runnable, JNIEnv *env, int timeoutMs = INT_MAX); Q_CORE_EXPORT void runOnUiThread(QRunnable *runnable, JNIEnv *env); + Q_CORE_EXPORT void requestPermissions(JNIEnv *env, const QStringList &permissions, const PermissionsResultFunc &callbackFunc, bool directCall = false); + Q_CORE_EXPORT QHash requestPermissionsSync(JNIEnv *env, const QStringList &permissions, int timeoutMs = INT_MAX); + Q_CORE_EXPORT PermissionsResult checkPermission(const QString &permission); + Q_CORE_EXPORT bool shouldShowRequestPermissionRationale(const QString &permission); Q_CORE_EXPORT void handleActivityResult(jint requestCode, jint resultCode, jobject data); Q_CORE_EXPORT void registerActivityResultListener(ActivityResultListener *listener); -- cgit v1.2.3 From 8d6f2e7e157d5778e37e54cd7e90c3185970abff Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 31 Aug 2016 15:39:30 +0200 Subject: Add a QT_REQUIRE_CONFIG(feature) macro This macro expands into a static_assert and can be used to trigger a compile error if a certain feature is not available when trying to compile some code. This is especially useful to protect against accidental inclusion of headers that implement functionality related to a feature. Change-Id: I456c55b989ce5f35f3af0e13c1886a85c23dfe29 Reviewed-by: Edward Welbourne Reviewed-by: Lars Knoll --- bin/syncqt.pl | 48 ++++++++++++++++++++++++++-------- mkspecs/features/qt_module_headers.prf | 11 ++++++-- src/corelib/global/qglobal.h | 1 + 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/bin/syncqt.pl b/bin/syncqt.pl index b531dce374..0435aead0a 100755 --- a/bin/syncqt.pl +++ b/bin/syncqt.pl @@ -200,9 +200,11 @@ sub shouldMasterInclude { } ###################################################################### -# Syntax: classNames(iheader, clean) +# Syntax: classNames(iheader, clean, requires) # Params: iheader, string, filename to parse for classname "symlinks" # (out) clean, boolean, will be set to false if the header isn't clean +# (out) requires, string, will be set to non-empty if the header +# requires a feature # # Purpose: Scans through iheader to find all classnames that should be # synced into library's include structure. @@ -210,8 +212,9 @@ sub shouldMasterInclude { ###################################################################### sub classNames { my @ret; - my ($iheader, $clean) = @_; + my ($iheader, $clean, $requires) = @_; $$clean = 1; + $$requires = ""; my $ihdrbase = basename($iheader); my $classname = $classnames{$ihdrbase}; @@ -236,6 +239,7 @@ sub classNames { $line .= ";" if($line =~ m/^QT_(BEGIN|END)_NAMESPACE(_[A-Z]+)*[\r\n]*$/); #qt macro $line .= ";" if($line =~ m/^QT_MODULE\(.*\)[\r\n]*$/); # QT_MODULE macro $line .= ";" if($line =~ m/^QT_WARNING_(PUSH|POP|DISABLE_\w+\(.*\))[\r\n]*$/); # qt macros + $$requires = $1 if ($line =~ m/^QT_REQUIRE_CONFIG\((.*)\);[\r\n]*$/); $parsable .= " " . $line; } } @@ -706,6 +710,21 @@ sub isQpaHeader return 0; } +sub globosort($$) { + my ($a, $b) = @_; + if ($a =~ /^q(.*)global\.h$/) { + my $sa = $1; + if ($b =~ /^q(.*)global\.h$/) { + my $sb = $1; + # Compare stems so qglobal.h (empty stem) is first: + return $sa cmp $sb; + } + return -1; # $a is global, so before $b + } + return +1 if $b =~ /^q.*global\.h$/; # $a not global, so after $b + return $a cmp $b; +} + # check if this is an in-source build, and if so use that as the basedir too $basedir = locateSyncProfile($out_basedir); if ($basedir) { @@ -914,10 +933,7 @@ foreach my $lib (@modules_to_sync) { my $pri_clean_files = ""; my $libcapitals = uc($lib); - my $master_contents = - "#ifndef QT_".$libcapitals."_MODULE_H\n" . - "#define QT_".$libcapitals."_MODULE_H\n" . - "#include <$lib/${lib}Depends>\n"; + my %master_contents = (); #remove the old files if($remove_stale) { @@ -1017,6 +1033,7 @@ foreach my $lib (@modules_to_sync) { } my $clean_header; + my $requires; my $iheader = $subdir . "/" . $header; $iheader =~ s/^\Q$basedir\E/$out_basedir/ if ($shadow); if ($check_includes) { @@ -1025,7 +1042,7 @@ foreach my $lib (@modules_to_sync) { && $header =~ /_p\.h$/ && $subdir !~ /3rdparty/; check_header($lib, $header, $iheader, $public_header, $private_header); } - my @classes = $public_header && (!$minimal && $is_qt) ? classNames($iheader, \$clean_header) : (); + my @classes = $public_header && (!$minimal && $is_qt) ? classNames($iheader, \$clean_header, \$requires) : (); if($showonly) { print "$header [$lib]\n"; foreach(@classes) { @@ -1059,7 +1076,7 @@ foreach my $lib (@modules_to_sync) { my $injection = ""; if($public_header) { #put it into the master file - $master_contents .= "#include \"$public_header\"\n" if (!$shadow && shouldMasterInclude($iheader)); + $master_contents{$public_header} = $requires if (!$shadow && shouldMasterInclude($iheader)); #deal with the install directives foreach my $class (@classes) { @@ -1074,7 +1091,7 @@ foreach my $lib (@modules_to_sync) { $injection .= ":$class"; } $pri_install_files.= "$pri_install_iheader ";; - $pri_clean_files .= "$pri_install_iheader " if ($clean_header); + $pri_clean_files .= "$pri_install_iheader".($requires ? ":".$requires : "")." " if ($clean_header); } elsif ($qpa_header) { $pri_install_qpafiles.= "$pri_install_iheader ";; @@ -1113,8 +1130,17 @@ foreach my $lib (@modules_to_sync) { } } - # close the master include: - $master_contents .= + # populate the master include: + my $master_contents = + "#ifndef QT_".$libcapitals."_MODULE_H\n" . + "#define QT_".$libcapitals."_MODULE_H\n" . + "#include <$lib/${lib}Depends>\n" . + join("", map { + my $rq = $master_contents{$_}; + ($rq ? "#if QT_CONFIG($rq)\n" : "") . + "#include \"$_\"\n" . + ($rq ? "#endif\n" : "") + } sort globosort keys %master_contents) . "#include \"".lc($lib)."version.h\"\n" . "#endif\n"; diff --git a/mkspecs/features/qt_module_headers.prf b/mkspecs/features/qt_module_headers.prf index 229760068e..5a45007820 100644 --- a/mkspecs/features/qt_module_headers.prf +++ b/mkspecs/features/qt_module_headers.prf @@ -243,16 +243,23 @@ headersclean:!internal_module { } !isEmpty(hcleanCOMMAND):if(!qtConfig(debug_and_release)|CONFIG(release, debug|release)) { + CLEAN_HEADERS = + for (h, SYNCQT.CLEAN_HEADER_FILES) { + hh = $$split(h, :) + hr = $$member(hh, 1) + isEmpty(hr)|qtConfig($$hr): \ + CLEAN_HEADERS += $$member(hh, 0) + } + CLEAN_HEADERS -= $$HEADERSCLEAN_EXCLUDE header_check.dependency_type = TYPE_C header_check.CONFIG += no_link header_check.output = ${QMAKE_VAR_OBJECTS_DIR}header_${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} - header_check.input = SYNCQT.CLEAN_HEADER_FILES + header_check.input = CLEAN_HEADERS header_check.variable_out = PRE_TARGETDEPS header_check.name = headercheck ${QMAKE_FILE_IN} header_check.commands = $$hcleanCOMMAND silent:header_check.commands = @echo compiling[header] ${QMAKE_FILE_IN} && $$hcleanCOMMAND QMAKE_EXTRA_COMPILERS += header_check - SYNCQT.CLEAN_HEADER_FILES -= $$HEADERSCLEAN_EXCLUDE } unset(hcleanCOMMAND) unset(hcleanFLAGS) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index f11ec127e0..dd8b6110b3 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -78,6 +78,7 @@ 1: The feature is available */ #define QT_CONFIG(feature) (1/QT_FEATURE_##feature == 1) +#define QT_REQUIRE_CONFIG(feature) Q_STATIC_ASSERT_X(QT_FEATURE_##feature == 1, "Required feature " #feature " for file " __FILE__ " not vailable.") #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) # define QT_NO_UNSHARABLE_CONTAINERS -- cgit v1.2.3 From a6bc0157eb5ec0fa9f5d27af9c10b6d9c85d5e18 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 13 Sep 2016 14:20:37 -0700 Subject: Correct the C++ standard references in QMutex functions Section 30.4.1.3 [thread.timedmutex.requirements] has 16 paragraphs and 2 subsections. Change-Id: I9093948278414644a416fffd1473fec7fdd2716c Reviewed-by: Marc Mutz Reviewed-by: Edward Welbourne --- src/corelib/thread/qmutex.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h index da8d1704b0..3a0e22e3bd 100644 --- a/src/corelib/thread/qmutex.h +++ b/src/corelib/thread/qmutex.h @@ -135,8 +135,8 @@ public: template bool try_lock_for(std::chrono::duration duration) { - // § 30.4.1.3.5 [thread.timedmutex.requirements] specifies that a - // duration less than or equal to duration.zero() shall result in a + // N4606 § 30.4.1.3 [thread.timedmutex.requirements]/5 specifies that + // a duration less than or equal to duration.zero() shall result in a // try_lock, unlike QMutex's tryLock with a negative duration which // results in a lock. @@ -150,7 +150,7 @@ public: bool try_lock_until(std::chrono::time_point timePoint) { // Implemented in terms of try_lock_for to honor the similar - // requirement in § 30.4.1.3.12 [thread.timedmutex.requirements] + // requirement in N4606 § 30.4.1.3 [thread.timedmutex.requirements]/12. return try_lock_for(timePoint - Clock::now()); } -- cgit v1.2.3 From 18ed6f20ad4327fa2ffbb687ac2f3ca7429c4348 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 15 Sep 2016 09:44:24 -0700 Subject: Change some #elif to #endif / #if in qcompilerdetection.h The conditions aren't exclusive, but complementary. This change removes one check for defined(Q_CC_INTEL) because it was disabled before and requires testing before we confirm it to be correct. Change-Id: I33dc971f005a4848bb8ffffd14748cde4dd23333 Reviewed-by: Marc Mutz --- src/corelib/global/qcompilerdetection.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index a48548bc90..a3d816f0c3 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -1031,7 +1031,8 @@ // critical definitions. (Reported as Intel Issue ID 6000117277) # define __USE_CONSTEXPR 1 # define __USE_NOEXCEPT 1 -# elif defined(Q_CC_MSVC) && (defined(Q_CC_CLANG) || defined(Q_CC_INTEL)) +# endif +# if defined(Q_CC_MSVC) && defined(Q_CC_CLANG) // Clang and the Intel compiler support more C++ features than the Microsoft compiler // so make sure we don't enable them if the MS headers aren't properly adapted. # ifndef _HAS_CONSTEXPR @@ -1058,7 +1059,8 @@ # ifndef _HAS_VARIADIC_TEMPLATES # undef Q_COMPILER_VARIADIC_TEMPLATES # endif -# elif defined(_LIBCPP_VERSION) +# endif +# if defined(_LIBCPP_VERSION) // libc++ uses __has_feature(cxx_atomic), so disable the feature if the compiler // doesn't support it. That's required for the Intel compiler 14.x or earlier on OS X, for example. # if !__has_feature(cxx_atomic) -- cgit v1.2.3 From 1b98ce1986ae96a0966f9ea075e327d641790343 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 20 Feb 2016 19:36:45 +0100 Subject: QSqlRelation: mark shared-come-qt6 ... and plaster API with nothrow (well, one function). Change-Id: I36fd64c6fda5390954c82bba307c720d3b3215df Reviewed-by: Thiago Macieira --- src/sql/models/qsqlrelationaltablemodel.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/sql/models/qsqlrelationaltablemodel.h b/src/sql/models/qsqlrelationaltablemodel.h index 4da460389c..f8b08b089f 100644 --- a/src/sql/models/qsqlrelationaltablemodel.h +++ b/src/sql/models/qsqlrelationaltablemodel.h @@ -43,6 +43,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE @@ -53,17 +55,26 @@ public: QSqlRelation(const QString &aTableName, const QString &indexCol, const QString &displayCol) : tName(aTableName), iColumn(indexCol), dColumn(displayCol) {} + + void swap(QSqlRelation &other) Q_DECL_NOTHROW + { + qSwap(tName, other.tName); + qSwap(iColumn, other.iColumn); + qSwap(dColumn, other.dColumn); + } + inline QString tableName() const { return tName; } inline QString indexColumn() const { return iColumn; } inline QString displayColumn() const { return dColumn; } - inline bool isValid() const + bool isValid() const Q_DECL_NOTHROW { return !(tName.isEmpty() || iColumn.isEmpty() || dColumn.isEmpty()); } private: QString tName, iColumn, dColumn; }; +Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QSqlRelation) class QSqlRelationalTableModelPrivate; -- cgit v1.2.3 From 542ba86e22a062445a57dc9aec3387d65258ab6b Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 22 Aug 2016 21:00:40 +0200 Subject: tests/auto/corelib/mimetypes: use local QThreadPool Isolates the test from anything that might be going on on the globalInstance(). Enabled by the explicit thread-pool feature on QtConcurrent::run(). Add explicit timed wait (unit tests should contain as little indefinite waits as possible). Also avoids the use of QFutureSynchronizer, which makes my static QList checker go nuts, with no way of fixing it until Qt 6. Change-Id: I0829992642b2a49bb6a10ddd4b31eb3f88e3adeb Reviewed-by: Thiago Macieira --- .../mimetypes/qmimedatabase/tst_qmimedatabase.cpp | 23 +++++++++++----------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp index 9e369792f1..2cf9ea4913 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -41,7 +41,6 @@ #include #include #include -#include #include #include @@ -844,18 +843,18 @@ void tst_QMimeDatabase::findByFile() void tst_QMimeDatabase::fromThreads() { - QThreadPool::globalInstance()->setMaxThreadCount(20); + QThreadPool tp; + tp.setMaxThreadCount(20); // Note that data-based tests cannot be used here (QTest::fetchData asserts). - QFutureSynchronizer sync; - sync.addFuture(QtConcurrent::run(this, &tst_QMimeDatabase::mimeTypeForName)); - sync.addFuture(QtConcurrent::run(this, &tst_QMimeDatabase::aliases)); - sync.addFuture(QtConcurrent::run(this, &tst_QMimeDatabase::allMimeTypes)); - sync.addFuture(QtConcurrent::run(this, &tst_QMimeDatabase::icons)); - sync.addFuture(QtConcurrent::run(this, &tst_QMimeDatabase::inheritance)); - sync.addFuture(QtConcurrent::run(this, &tst_QMimeDatabase::knownSuffix)); - sync.addFuture(QtConcurrent::run(this, &tst_QMimeDatabase::mimeTypeForFileWithContent)); - sync.addFuture(QtConcurrent::run(this, &tst_QMimeDatabase::allMimeTypes)); // a second time - // sync dtor blocks waiting for finished + QtConcurrent::run(&tp, this, &tst_QMimeDatabase::mimeTypeForName); + QtConcurrent::run(&tp, this, &tst_QMimeDatabase::aliases); + QtConcurrent::run(&tp, this, &tst_QMimeDatabase::allMimeTypes); + QtConcurrent::run(&tp, this, &tst_QMimeDatabase::icons); + QtConcurrent::run(&tp, this, &tst_QMimeDatabase::inheritance); + QtConcurrent::run(&tp, this, &tst_QMimeDatabase::knownSuffix); + QtConcurrent::run(&tp, this, &tst_QMimeDatabase::mimeTypeForFileWithContent); + QtConcurrent::run(&tp, this, &tst_QMimeDatabase::allMimeTypes); // a second time + QVERIFY(tp.waitForDone(60000)); } #ifndef QT_NO_PROCESS -- cgit v1.2.3 From c52bb0309071bed9e040c79d87f764bac6a396b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 12 Sep 2016 17:05:39 +0200 Subject: macOS: Move QMacCGContext helper into QtGui MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The implementation was duplicated and spread out between QMacStyle, QMacPaintEngine, and the Cocoa platform plugin. Moving it into QtGui allows using it on other Apple platform. Change-Id: Iadcbd71998204887e116271c575037789b6e2163 Reviewed-by: Jake Petroules Reviewed-by: Tor Arne Vestbø --- src/gui/painting/painting.pri | 5 + src/gui/painting/qcoregraphics.mm | 289 +++++++++++++++++++++++ src/gui/painting/qcoregraphics_p.h | 99 ++++++++ src/gui/painting/qpaintengine_p.h | 5 + src/plugins/platforms/cocoa/qcocoahelpers.h | 5 - src/plugins/platforms/cocoa/qcocoahelpers.mm | 138 +---------- src/plugins/platforms/cocoa/qcocoaintegration.mm | 7 +- src/plugins/platforms/cocoa/qcocoatheme.mm | 4 +- src/plugins/platforms/cocoa/qpaintengine_mac.mm | 84 +------ src/plugins/platforms/cocoa/qprintengine_mac_p.h | 3 + src/plugins/platforms/cocoa/qt_mac_p.h | 38 --- src/widgets/styles/qmacstyle_mac.mm | 279 +--------------------- 12 files changed, 415 insertions(+), 541 deletions(-) create mode 100644 src/gui/painting/qcoregraphics.mm create mode 100644 src/gui/painting/qcoregraphics_p.h diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index c47060a2ad..a61865a0b6 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -99,6 +99,11 @@ SOURCES += \ painting/qplatformbackingstore.cpp \ painting/qpathsimplifier.cpp +darwin { + HEADERS += painting/qcoregraphics_p.h + SOURCES += painting/qcoregraphics.mm +} + SSE2_SOURCES += painting/qdrawhelper_sse2.cpp SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \ diff --git a/src/gui/painting/qcoregraphics.mm b/src/gui/painting/qcoregraphics.mm new file mode 100644 index 0000000000..fa5c9b61b2 --- /dev/null +++ b/src/gui/painting/qcoregraphics.mm @@ -0,0 +1,289 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcoregraphics_p.h" + +#include +#include + +#include +#include +#include + +QT_BEGIN_NAMESPACE + + +// ---------------------- Color Management ---------------------- + +static CGColorSpaceRef m_genericColorSpace = 0; +static QHash m_displayColorSpaceHash; +static bool m_postRoutineRegistered = false; + +static void qt_mac_cleanUpMacColorSpaces() +{ + if (m_genericColorSpace) { + CFRelease(m_genericColorSpace); + m_genericColorSpace = 0; + } + QHash::const_iterator it = m_displayColorSpaceHash.constBegin(); + while (it != m_displayColorSpaceHash.constEnd()) { + if (it.value()) + CFRelease(it.value()); + ++it; + } + m_displayColorSpaceHash.clear(); +} + +static CGColorSpaceRef qt_mac_displayColorSpace(const QWindow *window) +{ + CGColorSpaceRef colorSpace = 0; + uint32_t displayID = 0; + +#ifdef Q_OS_MACOS + if (window == 0) { + displayID = CGMainDisplayID(); + } else { + displayID = CGMainDisplayID(); + /* + ### get correct display + const QRect &qrect = window->geometry(); + CGRect rect = CGRectMake(qrect.x(), qrect.y(), qrect.width(), qrect.height()); + CGDisplayCount throwAway; + CGDisplayErr dErr = CGGetDisplaysWithRect(rect, 1, &displayID, &throwAway); + if (dErr != kCGErrorSuccess) + return macDisplayColorSpace(0); // fall back on main display + */ + } + if ((colorSpace = m_displayColorSpaceHash.value(displayID))) + return colorSpace; + + colorSpace = CGDisplayCopyColorSpace(displayID); +#else + Q_UNUSED(window); +#endif + + if (colorSpace == 0) + colorSpace = CGColorSpaceCreateDeviceRGB(); + + m_displayColorSpaceHash.insert(displayID, colorSpace); + if (!m_postRoutineRegistered) { + m_postRoutineRegistered = true; + qAddPostRoutine(qt_mac_cleanUpMacColorSpaces); + } + return colorSpace; +} + +CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice) +{ + Q_UNUSED(paintDevice); + + // FIXME: Move logic into each paint device once Qt has support for color spaces + return qt_mac_displayColorSpace(0); + + // The following code seems to take care of QWidget, but in reality doesn't, as + // qt_mac_displayColorSpace ignores the argument and always uses the main display. +#if 0 + bool isWidget = (paintDevice->devType() == QInternal::Widget); + return qt_mac_displayColorSpace(isWidget ? static_cast(paintDevice)->window() : 0); +#endif +} + +CGColorSpaceRef qt_mac_genericColorSpace() +{ +#if 0 + if (!m_genericColorSpace) { + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { + m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + } else + { + m_genericColorSpace = CGColorSpaceCreateDeviceRGB(); + } + if (!m_postRoutineRegistered) { + m_postRoutineRegistered = true; + qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces); + } + } + return m_genericColorSpace; +#else + // Just return the main display colorspace for the moment. + return qt_mac_displayColorSpace(0); +#endif +} + +// ---------------------- Geometry Helpers ---------------------- + +void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform) +{ + CGAffineTransform old_xform = CGAffineTransformIdentity; + if (orig_xform) { //setup xforms + old_xform = CGContextGetCTM(hd); + CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform)); + CGContextConcatCTM(hd, *orig_xform); + } + + //do the clipping + CGContextBeginPath(hd); + if (rgn.isEmpty()) { + CGContextAddRect(hd, CGRectMake(0, 0, 0, 0)); + } else { + for (const QRect &r : rgn) { + CGRect mac_r = CGRectMake(r.x(), r.y(), r.width(), r.height()); + CGContextAddRect(hd, mac_r); + } + } + CGContextClip(hd); + + if (orig_xform) {//reset xforms + CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd))); + CGContextConcatCTM(hd, old_xform); + } +} + +// move to QRegion? +void qt_mac_scale_region(QRegion *region, qreal scaleFactor) +{ + if (!region || !region->rectCount()) + return; + + QVector scaledRects; + scaledRects.reserve(region->rectCount()); + + for (const QRect &rect : *region) + scaledRects.append(QRect(rect.topLeft() * scaleFactor, rect.size() * scaleFactor)); + + region->setRects(&scaledRects[0], scaledRects.count()); +} + +// ---------------------- QMacCGContext ---------------------- + +QMacCGContext::QMacCGContext(QPaintDevice *paintDevice) : context(0) +{ + // In Qt 5, QWidget and QPixmap (and QImage) paint devices are all QImages under the hood. + QImage *image = 0; + if (paintDevice->devType() == QInternal::Image) { + image = static_cast(paintDevice); + } else if (paintDevice->devType() == QInternal::Pixmap) { + + const QPixmap *pm = static_cast(paintDevice); + QPlatformPixmap *data = const_cast(pm)->data_ptr().data(); + if (data && data->classId() == QPlatformPixmap::RasterClass) { + image = data->buffer(); + } else { + qDebug("QMacCGContext: Unsupported pixmap class"); + } + } else if (paintDevice->devType() == QInternal::Widget) { + // TODO test: image = static_cast(static_cast(paintDevice)->backingStore()->paintDevice()); + qDebug("QMacCGContext: not implemented: Widget class"); + } + + if (!image) + return; // Context type not supported. + + CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(paintDevice); + uint flags = kCGImageAlphaPremultipliedFirst; + flags |= kCGBitmapByteOrder32Host; + + context = CGBitmapContextCreate(image->bits(), image->width(), image->height(), + 8, image->bytesPerLine(), colorspace, flags); + CGContextTranslateCTM(context, 0, image->height()); + CGContextScaleCTM(context, 1, -1); +} + +QMacCGContext::QMacCGContext(QPainter *painter) : context(0) +{ + QPaintEngine *paintEngine = painter->paintEngine(); + + // Handle the case of QMacPrintEngine, which has an internal QCoreGraphicsPaintEngine + while (QPaintEngine *aggregateEngine = QPaintEnginePrivate::get(paintEngine)->aggregateEngine()) + paintEngine = aggregateEngine; + + paintEngine->syncState(); + + if (Qt::HANDLE handle = QPaintEnginePrivate::get(paintEngine)->nativeHandle()) { + context = static_cast(handle); + return; + } + + int devType = painter->device()->devType(); + if (paintEngine->type() == QPaintEngine::Raster + && (devType == QInternal::Widget || + devType == QInternal::Pixmap || + devType == QInternal::Image)) { + + CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(paintEngine->paintDevice()); + uint flags = kCGImageAlphaPremultipliedFirst; +#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version + flags |= kCGBitmapByteOrder32Host; +#endif + const QImage *image = static_cast(paintEngine->paintDevice()); + + context = CGBitmapContextCreate((void *)image->bits(), image->width(), image->height(), + 8, image->bytesPerLine(), colorspace, flags); + + // Invert y axis + CGContextTranslateCTM(context, 0, image->height()); + CGContextScaleCTM(context, 1, -1); + + const qreal devicePixelRatio = image->devicePixelRatio(); + + if (devType == QInternal::Widget) { + // Set the clip rect which is an intersection of the system clip + // and the painter clip. To make matters more interesting these + // are in device pixels and device-independent pixels, respectively. + QRegion clip = painter->paintEngine()->systemClip(); // get system clip in device pixels + QTransform native = painter->deviceTransform(); // get device transform. dx/dy is in device pixels + + if (painter->hasClipping()) { + QRegion r = painter->clipRegion(); // get painter clip, which is in device-independent pixels + qt_mac_scale_region(&r, devicePixelRatio); // scale painter clip to device pixels + r.translate(native.dx(), native.dy()); + if (clip.isEmpty()) + clip = r; + else + clip &= r; + } + qt_mac_clip_cg(context, clip, 0); // clip in device pixels + + // Scale the context so that painting happens in device-independent pixels + CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio); + CGContextTranslateCTM(context, native.dx() / devicePixelRatio, native.dy() / devicePixelRatio); + } else { + // Scale to paint in device-independent pixels + CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio); + } + } else { + qDebug() << "QMacCGContext:: Unsupported painter devtype type" << devType; + } +} + +QT_END_NAMESPACE diff --git a/src/gui/painting/qcoregraphics_p.h b/src/gui/painting/qcoregraphics_p.h new file mode 100644 index 0000000000..b6ea5474ec --- /dev/null +++ b/src/gui/painting/qcoregraphics_p.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCOREGRAPHICS_P_H +#define QCOREGRAPHICS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +Q_GUI_EXPORT CGColorSpaceRef qt_mac_genericColorSpace(); +Q_GUI_EXPORT CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice); + +Q_GUI_EXPORT void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform); + +class Q_GUI_EXPORT QMacCGContext +{ +public: + inline QMacCGContext() { context = 0; } + QMacCGContext(QPaintDevice *pdev); + QMacCGContext(QPainter *p); + inline QMacCGContext(CGContextRef cg, bool takeOwnership = false) { + context = cg; + if (!takeOwnership) + CGContextRetain(context); + } + inline QMacCGContext(const QMacCGContext ©) : context(0) { *this = copy; } + inline ~QMacCGContext() { + if (context) + CGContextRelease(context); + } + inline bool isNull() const { return context; } + inline operator CGContextRef() { return context; } + inline QMacCGContext &operator=(const QMacCGContext ©) { + if (context) + CGContextRelease(context); + context = copy.context; + CGContextRetain(context); + return *this; + } + inline QMacCGContext &operator=(CGContextRef cg) { + if (context) + CGContextRelease(context); + context = cg; + CGContextRetain(context); //we do not take ownership + return *this; + } + +private: + CGContextRef context; +}; + +QT_END_NAMESPACE + +#endif // QCOREGRAPHICS_P_H diff --git a/src/gui/painting/qpaintengine_p.h b/src/gui/painting/qpaintengine_p.h index 1a1df547bb..9d511f9bad 100644 --- a/src/gui/painting/qpaintengine_p.h +++ b/src/gui/painting/qpaintengine_p.h @@ -118,6 +118,11 @@ public: virtual void systemStateChanged() { } void drawBoxTextItem(const QPointF &p, const QTextItemInt &ti); + + static QPaintEnginePrivate *get(QPaintEngine *paintEngine) { return paintEngine->d_func(); } + + virtual QPaintEngine *aggregateEngine() { return 0; } + virtual Qt::HANDLE nativeHandle() { return 0; } }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index 9b061bbae8..272b443b68 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -95,9 +95,6 @@ Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions); // Misc void qt_mac_transformProccessToForegroundApplication(); -CGColorSpaceRef qt_mac_genericColorSpace(); -CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget); -CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice); QString qt_mac_applicationName(); int qt_mac_flipYCoordinate(int y); @@ -143,8 +140,6 @@ public: } }; -CGContextRef qt_mac_cg_context(QPaintDevice *pdev); - template T qt_mac_resolveOption(const T &fallback, const QByteArray &environment) { diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 6920f75887..21ffd8599f 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -47,6 +47,7 @@ #include #include #include +#include #ifndef QT_NO_WIDGETS #include @@ -402,97 +403,6 @@ void qt_mac_transformProccessToForegroundApplication() [[NSApplication sharedApplication] setActivationPolicy:NSApplicationActivationPolicyRegular]; } } -static CGColorSpaceRef m_genericColorSpace = 0; -static QHash m_displayColorSpaceHash; -static bool m_postRoutineRegistered = false; - -CGColorSpaceRef qt_mac_genericColorSpace() -{ -#if 0 - if (!m_genericColorSpace) { - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { - m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); - } else - { - m_genericColorSpace = CGColorSpaceCreateDeviceRGB(); - } - if (!m_postRoutineRegistered) { - m_postRoutineRegistered = true; - qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces); - } - } - return m_genericColorSpace; -#else - // Just return the main display colorspace for the moment. - return qt_mac_displayColorSpace(0); -#endif -} - -/* - Ideally, we should pass the widget in here, and use CGGetDisplaysWithRect() etc. - to support multiple displays correctly. -*/ -CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget) -{ - CGColorSpaceRef colorSpace; - - CGDirectDisplayID displayID; - if (widget == 0) { - displayID = CGMainDisplayID(); - } else { - displayID = CGMainDisplayID(); - /* - ### get correct display - const QRect &qrect = widget->window()->geometry(); - CGRect rect = CGRectMake(qrect.x(), qrect.y(), qrect.width(), qrect.height()); - CGDisplayCount throwAway; - CGDisplayErr dErr = CGGetDisplaysWithRect(rect, 1, &displayID, &throwAway); - if (dErr != kCGErrorSuccess) - return macDisplayColorSpace(0); // fall back on main display - */ - } - if ((colorSpace = m_displayColorSpaceHash.value(displayID))) - return colorSpace; - - colorSpace = CGDisplayCopyColorSpace(displayID); - if (colorSpace == 0) - colorSpace = CGColorSpaceCreateDeviceRGB(); - - m_displayColorSpaceHash.insert(displayID, colorSpace); - if (!m_postRoutineRegistered) { - m_postRoutineRegistered = true; - void qt_mac_cleanUpMacColorSpaces(); - qAddPostRoutine(qt_mac_cleanUpMacColorSpaces); - } - return colorSpace; -} - -void qt_mac_cleanUpMacColorSpaces() -{ - if (m_genericColorSpace) { - CFRelease(m_genericColorSpace); - m_genericColorSpace = 0; - } - QHash::const_iterator it = m_displayColorSpaceHash.constBegin(); - while (it != m_displayColorSpaceHash.constEnd()) { - if (it.value()) - CFRelease(it.value()); - ++it; - } - m_displayColorSpaceHash.clear(); -} - -CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice) -{ -#ifdef QT_NO_WIDGETS - Q_UNUSED(paintDevice) - return qt_mac_displayColorSpace(0); -#else - bool isWidget = (paintDevice->devType() == QInternal::Widget); - return qt_mac_displayColorSpace(isWidget ? static_cast(paintDevice): 0); -#endif - -} QString qt_mac_applicationName() { @@ -599,49 +509,6 @@ QString qt_mac_removeAmpersandEscapes(QString s) return QPlatformTheme::removeMnemonics(s).trimmed(); } -/*! \internal - - Returns the CoreGraphics CGContextRef of the paint device. 0 is - returned if it can't be obtained. It is the caller's responsibility to - CGContextRelease the context when finished using it. - - \warning This function is only available on \macos. - \warning This function is duplicated in qmacstyle_mac.mm - */ -CGContextRef qt_mac_cg_context(QPaintDevice *pdev) -{ - // In Qt 5, QWidget and QPixmap (and QImage) paint devices are all QImages under the hood. - QImage *image = 0; - if (pdev->devType() == QInternal::Image) { - image = static_cast(pdev); - } else if (pdev->devType() == QInternal::Pixmap) { - - const QPixmap *pm = static_cast(pdev); - QPlatformPixmap *data = const_cast(pm)->data_ptr().data(); - if (data && data->classId() == QPlatformPixmap::RasterClass) { - image = data->buffer(); - } else { - qDebug("qt_mac_cg_context: Unsupported pixmap class"); - } - } else if (pdev->devType() == QInternal::Widget) { - // TODO test: image = static_cast(static_cast(pdev)->backingStore()->paintDevice()); - qDebug("qt_mac_cg_context: not implemented: Widget class"); - } - - if (!image) - return 0; // Context type not supported. - - CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev); - uint flags = kCGImageAlphaPremultipliedFirst; - flags |= kCGBitmapByteOrder32Host; - CGContextRef ret = 0; - ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(), - 8, image->bytesPerLine(), colorspace, flags); - CGContextTranslateCTM(ret, 0, image->height()); - CGContextScaleCTM(ret, 1, -1); - return ret; -} - QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size) { const NSSize pixmapSize = NSMakeSize(size.width(), size.height()); @@ -669,9 +536,8 @@ QImage qt_mac_toQImage(CGImageRef image) QImage ret(w, h, QImage::Format_ARGB32_Premultiplied); ret.fill(Qt::transparent); CGRect rect = CGRectMake(0, 0, w, h); - CGContextRef ctx = qt_mac_cg_context(&ret); + QMacCGContext ctx(&ret); qt_mac_drawCGImage(ctx, &rect, image); - CGContextRelease(ctx); return ret; } diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 1793bd404e..f3f720654e 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -58,6 +58,8 @@ #include #include +#include + #include static void initResources() @@ -199,8 +201,6 @@ QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const return window; } -extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev); - QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height) const { // TODO window should be handled @@ -251,9 +251,8 @@ QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height QPixmap pix(w, h); pix.fill(Qt::transparent); CGRect rect = CGRectMake(0, 0, w, h); - CGContextRef ctx = qt_mac_cg_context(&pix); + QMacCGContext ctx(&pix); qt_mac_drawCGImage(ctx, &rect, image); - CGContextRelease(ctx); QPainter painter(&windowPixmap); painter.drawPixmap(0, 0, pix); diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index 95175871a4..d0879ed457 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -56,6 +56,7 @@ #include #include +#include #include #include #include @@ -197,7 +198,7 @@ QPixmap qt_mac_convert_iconref(const IconRef icon, int width, int height) CGRect rect = CGRectMake(0, 0, width, height); - CGContextRef ctx = qt_mac_cg_context(&ret); + QMacCGContext ctx(&ret); CGAffineTransform old_xform = CGContextGetCTM(ctx); CGContextConcatCTM(ctx, CGAffineTransformInvert(old_xform)); CGContextConcatCTM(ctx, CGAffineTransformIdentity); @@ -205,7 +206,6 @@ QPixmap qt_mac_convert_iconref(const IconRef icon, int width, int height) ::RGBColor b; b.blue = b.green = b.red = 255*255; PlotIconRefInContext(ctx, &rect, kAlignNone, kTransformNone, &b, kPlotIconRefNormalFlags, icon); - CGContextRelease(ctx); return ret; } diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm index 759c4d26a5..7e241e3ae6 100644 --- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm @@ -63,6 +63,7 @@ #include #include #include +#include #include "qcocoahelpers.h" @@ -74,84 +75,6 @@ QT_BEGIN_NAMESPACE QCoreGraphicsPaintEngine utility functions *****************************************************************************/ -static void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform) -{ - CGAffineTransform old_xform = CGAffineTransformIdentity; - if (orig_xform) { //setup xforms - old_xform = CGContextGetCTM(hd); - CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform)); - CGContextConcatCTM(hd, *orig_xform); - } - - //do the clipping - CGContextBeginPath(hd); - if (rgn.isEmpty()) { - CGContextAddRect(hd, CGRectMake(0, 0, 0, 0)); - } else { - for (const QRect &r : rgn) { - CGRect mac_r = CGRectMake(r.x(), r.y(), r.width(), r.height()); - CGContextAddRect(hd, mac_r); - } - } - CGContextClip(hd); - - if (orig_xform) {//reset xforms - CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd))); - CGContextConcatCTM(hd, old_xform); - } -} - -// Implemented for qt_mac_p.h -QMacCGContext::QMacCGContext(QPainter *p) -{ - QPaintEngine *pe = p->paintEngine(); -#ifndef QT_NO_PRINTER - if (pe->type() == QPaintEngine::MacPrinter) - pe = static_cast(pe)->paintEngine(); -#endif - pe->syncState(); - context = 0; - if (pe->type() == QPaintEngine::CoreGraphics) - context = static_cast(pe)->handle(); - - int devType = p->device()->devType(); - if (pe->type() == QPaintEngine::Raster - && (devType == QInternal::Widget || devType == QInternal::Pixmap || devType == QInternal::Image)) { - - CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pe->paintDevice()); - uint flags = kCGImageAlphaPremultipliedFirst; -#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version - flags |= kCGBitmapByteOrder32Host; -#endif - const QImage *image = (const QImage *) pe->paintDevice(); - - context = CGBitmapContextCreate((void *) image->bits(), image->width(), image->height(), - 8, image->bytesPerLine(), colorspace, flags); - - CGContextTranslateCTM(context, 0, image->height()); - CGContextScaleCTM(context, 1, -1); - - if (devType == QInternal::Widget) { - QRegion clip = p->paintEngine()->systemClip(); - QTransform native = p->deviceTransform(); - - if (p->hasClipping()) { - QRegion r = p->clipRegion(); - r.translate(native.dx(), native.dy()); - if (clip.isEmpty()) - clip = r; - else - clip &= r; - } - qt_mac_clip_cg(context, clip, 0); - - CGContextTranslateCTM(context, native.dx(), native.dy()); - } - } else { - CGContextRetain(context); - } -} - void qt_mac_cgimage_data_free(void *, const void *memoryToFree, size_t) { free(const_cast(memoryToFree)); @@ -453,7 +376,7 @@ static void qt_mac_draw_pattern(void *info, CGContextRef c) const QColor c0(0, 0, 0, 0), c1(255, 255, 255, 255); QPixmap pm(w*QMACPATTERN_MASK_MULTIPLIER, h*QMACPATTERN_MASK_MULTIPLIER); pm.fill(c0); - CGContextRef pm_ctx = qt_mac_cg_context(&pm); + QMacCGContext pm_ctx(&pm); CGContextSetFillColorWithColor(c, cgColorForQColor(c1, pat->pdev)); CGRect rect = CGRectMake(0, 0, w, h); for (int x = 0; x < QMACPATTERN_MASK_MULTIPLIER; ++x) { @@ -543,7 +466,8 @@ QCoreGraphicsPaintEngine::begin(QPaintDevice *pdev) d->cosmeticPenSize = 1; d->current.clipEnabled = false; d->pixelSize = QPoint(1,1); - d->hd = qt_mac_cg_context(pdev); + QMacCGContext ctx(pdev); + d->hd = CGContextRetain(ctx); if (d->hd) { d->saveGraphicsState(); d->orig_xform = CGContextGetCTM(d->hd); diff --git a/src/plugins/platforms/cocoa/qprintengine_mac_p.h b/src/plugins/platforms/cocoa/qprintengine_mac_p.h index e3cad3fd57..ee98275b63 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac_p.h +++ b/src/plugins/platforms/cocoa/qprintengine_mac_p.h @@ -149,6 +149,9 @@ public: PMPageFormat format() const { return static_cast([printInfo PMPageFormat]); } PMPrintSession session() const { return static_cast([printInfo PMPrintSession]); } PMPrintSettings settings() const { return static_cast([printInfo PMPrintSettings]); } + + QPaintEngine *aggregateEngine() Q_DECL_OVERRIDE { return paintEngine; } + Qt::HANDLE nativeHandle() Q_DECL_OVERRIDE { return q_func()->handle(); } }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qt_mac_p.h b/src/plugins/platforms/cocoa/qt_mac_p.h index 902cf5c636..ce17919e8c 100644 --- a/src/plugins/platforms/cocoa/qt_mac_p.h +++ b/src/plugins/platforms/cocoa/qt_mac_p.h @@ -90,44 +90,6 @@ public: } }; -class QMacCGContext -{ - CGContextRef context; -public: - QMacCGContext(QPainter *p); //qpaintengine_mac.mm - inline QMacCGContext() { context = 0; } - inline QMacCGContext(QPaintDevice *pdev) { - extern CGContextRef qt_mac_cg_context(QPaintDevice *); - context = qt_mac_cg_context(pdev); - } - inline QMacCGContext(CGContextRef cg, bool takeOwnership=false) { - context = cg; - if(!takeOwnership) - CGContextRetain(context); - } - inline QMacCGContext(const QMacCGContext ©) : context(0) { *this = copy; } - inline ~QMacCGContext() { - if(context) - CGContextRelease(context); - } - inline bool isNull() const { return context; } - inline operator CGContextRef() { return context; } - inline QMacCGContext &operator=(const QMacCGContext ©) { - if(context) - CGContextRelease(context); - context = copy.context; - CGContextRetain(context); - return *this; - } - inline QMacCGContext &operator=(CGContextRef cg) { - if(context) - CGContextRelease(context); - context = cg; - CGContextRetain(context); //we do not take ownership - return *this; - } -}; - class QMacInternalPasteboardMime; class QMimeData; diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 6aa5845a2c..1f17810fc9 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -96,6 +96,7 @@ #include #include #include +#include QT_USE_NAMESPACE @@ -520,47 +521,6 @@ static QString qt_mac_removeMnemonics(const QString &original) return returnText; } -static CGContextRef qt_mac_cg_context(const QPaintDevice *pdev); - -namespace { -class QMacCGContext -{ - CGContextRef context; -public: - QMacCGContext(QPainter *p); - inline QMacCGContext() { context = 0; } - inline QMacCGContext(const QPaintDevice *pdev) { - context = qt_mac_cg_context(pdev); - } - inline QMacCGContext(CGContextRef cg, bool takeOwnership=false) { - context = cg; - if (!takeOwnership) - CGContextRetain(context); - } - inline QMacCGContext(const QMacCGContext ©) : context(0) { *this = copy; } - inline ~QMacCGContext() { - if (context) - CGContextRelease(context); - } - inline bool isNull() const { return context; } - inline operator CGContextRef() { return context; } - inline QMacCGContext &operator=(const QMacCGContext ©) { - if (context) - CGContextRelease(context); - context = copy.context; - CGContextRetain(context); - return *this; - } - inline QMacCGContext &operator=(CGContextRef cg) { - if (context) - CGContextRelease(context); - context = cg; - CGContextRetain(context); //we do not take ownership - return *this; - } -}; -} // anonymous namespace - OSStatus qt_mac_shape2QRegionHelper(int inMessage, HIShapeRef, const CGRect *inRect, void *inRefcon) { QRegion *region = static_cast(inRefcon); @@ -581,7 +541,6 @@ OSStatus qt_mac_shape2QRegionHelper(int inMessage, HIShapeRef, const CGRect *inR return noErr; } - /*! \internal Create's a mutable shape, it's the caller's responsibility to release. @@ -611,86 +570,6 @@ QRegion qt_mac_fromHIShapeRef(HIShapeRef shape) return returnRegion; } -CGColorSpaceRef m_genericColorSpace = 0; -static QHash m_displayColorSpaceHash; -bool m_postRoutineRegistered = false; - -static CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget); -static CGColorSpaceRef qt_mac_genericColorSpace() -{ -#if 0 - if (!m_genericColorSpace) { - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { - m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); - } else - { - m_genericColorSpace = CGColorSpaceCreateDeviceRGB(); - } - if (!m_postRoutineRegistered) { - m_postRoutineRegistered = true; - qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces); - } - } - return m_genericColorSpace; -#else - // Just return the main display colorspace for the moment. - return qt_mac_displayColorSpace(0); -#endif -} - -static void qt_mac_cleanUpMacColorSpaces() -{ - if (m_genericColorSpace) { - CFRelease(m_genericColorSpace); - m_genericColorSpace = 0; - } - QHash::const_iterator it = m_displayColorSpaceHash.constBegin(); - while (it != m_displayColorSpaceHash.constEnd()) { - if (it.value()) - CFRelease(it.value()); - ++it; - } - m_displayColorSpaceHash.clear(); -} - -/* - Ideally, we should pass the widget in here, and use CGGetDisplaysWithRect() etc. - to support multiple displays correctly. -*/ -static CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget) -{ - CGColorSpaceRef colorSpace; - - CGDirectDisplayID displayID; - if (widget == 0) { - displayID = CGMainDisplayID(); - } else { - displayID = CGMainDisplayID(); - /* - ### get correct display - const QRect &qrect = widget->window()->geometry(); - CGRect rect = CGRectMake(qrect.x(), qrect.y(), qrect.width(), qrect.height()); - CGDisplayCount throwAway; - CGDisplayErr dErr = CGGetDisplaysWithRect(rect, 1, &displayID, &throwAway); - if (dErr != kCGErrorSuccess) - return macDisplayColorSpace(0); // fall back on main display - */ - } - if ((colorSpace = m_displayColorSpaceHash.value(displayID))) - return colorSpace; - - colorSpace = CGDisplayCopyColorSpace(displayID); - if (colorSpace == 0) - colorSpace = CGColorSpaceCreateDeviceRGB(); - - m_displayColorSpaceHash.insert(displayID, colorSpace); - if (!m_postRoutineRegistered) { - m_postRoutineRegistered = true; - qAddPostRoutine(qt_mac_cleanUpMacColorSpaces); - } - return colorSpace; -} - bool qt_macWindowIsTextured(const QWidget *window) { if (QWindow *w = window->windowHandle()) @@ -2283,7 +2162,7 @@ void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush painter->setClipRegion(rgn); - QCFType cg = qt_mac_cg_context(target); + QMacCGContext cg(target); CGContextSaveGState(cg); HIThemeSetFill(kThemeBrushDialogBackgroundActive, 0, cg, kHIThemeOrientationInverted); @@ -2357,7 +2236,7 @@ void QMacStyle::polish(QWidget* w) mtinfo.menuType = kThemeMenuTypePopUp; // HIRect rect = CGRectMake(0, 0, px.width(), px.height()); // ### - //HIThemeDrawMenuBackground(&rect, &mtinfo, QCFType(qt_mac_cg_context(&px)), + //HIThemeDrawMenuBackground(&rect, &mtinfo, QMacCGContext(&px)), // kHIThemeOrientationNormal); QPalette pal = w->palette(); QBrush background(px); @@ -7187,158 +7066,6 @@ int QMacStyle::layoutSpacing(QSizePolicy::ControlType control1, return_SIZE(10, 8, 6); // guess } -static void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform) -{ - CGAffineTransform old_xform = CGAffineTransformIdentity; - if (orig_xform) { //setup xforms - old_xform = CGContextGetCTM(hd); - CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform)); - CGContextConcatCTM(hd, *orig_xform); - } - - //do the clipping - CGContextBeginPath(hd); - if (rgn.isEmpty()) { - CGContextAddRect(hd, CGRectMake(0, 0, 0, 0)); - } else { - QCFType shape = qt_mac_toHIMutableShape(rgn); - Q_ASSERT(!HIShapeIsEmpty(shape)); - HIShapeReplacePathInCGContext(shape, hd); - } - CGContextClip(hd); - - if (orig_xform) {//reset xforms - CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd))); - CGContextConcatCTM(hd, old_xform); - } -} - -// move to QRegion? -void qt_mac_scale_region(QRegion *region, qreal scaleFactor) -{ - if (!region || !region->rectCount()) - return; - - QVector scaledRects; - scaledRects.reserve(region->rectCount()); - - for (const QRect &rect : *region) - scaledRects.append(QRect(rect.topLeft() * scaleFactor, rect.size() * scaleFactor)); - - region->setRects(&scaledRects[0], scaledRects.count()); -} - -static CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice); - -namespace { -QMacCGContext::QMacCGContext(QPainter *p) -{ - QPaintEngine *pe = p->paintEngine(); - pe->syncState(); - context = 0; - - int devType = p->device()->devType(); - if (pe->type() == QPaintEngine::Raster - && (devType == QInternal::Widget || - devType == QInternal::Pixmap || - devType == QInternal::Image)) { - - CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pe->paintDevice()); - uint flags = kCGImageAlphaPremultipliedFirst; - flags |= kCGBitmapByteOrder32Host; - - const QImage *image = (const QImage *) pe->paintDevice(); - - context = CGBitmapContextCreate((void *) image->bits(), image->width(), image->height(), - 8, image->bytesPerLine(), colorspace, flags); - - // Invert y axis. - CGContextTranslateCTM(context, 0, image->height()); - CGContextScaleCTM(context, 1, -1); - - const qreal devicePixelRatio = image->devicePixelRatio(); - - if (devType == QInternal::Widget) { - // Set the clip rect which is an intersection of the system clip - // and the painter clip. To make matters more interesting these - // are in device pixels and device-independent pixels, respectively. - QRegion clip = p->paintEngine()->systemClip(); // get system clip in device pixels - QTransform native = p->deviceTransform(); // get device transform. dx/dy is in device pixels - - if (p->hasClipping()) { - QRegion r = p->clipRegion(); // get painter clip, which is in device-independent pixels - qt_mac_scale_region(&r, devicePixelRatio); // scale painter clip to device pixels - r.translate(native.dx(), native.dy()); - if (clip.isEmpty()) - clip = r; - else - clip &= r; - } - qt_mac_clip_cg(context, clip, 0); // clip in device pixels - - // Scale the context so that painting happens in device-independet pixels. - CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio); - CGContextTranslateCTM(context, native.dx() / devicePixelRatio, native.dy() / devicePixelRatio); - } else { - // Scale to paint in device-independent pixels. - CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio); - } - } else { - qDebug() << "QMacCGContext:: Unsupported painter devtype type" << devType; - } -} - -} // anonymous namespace - -static CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice) -{ - bool isWidget = (paintDevice->devType() == QInternal::Widget); - return qt_mac_displayColorSpace(isWidget ? static_cast(paintDevice) : 0); -} - -/*! \internal - - Returns the CoreGraphics CGContextRef of the paint device. 0 is - returned if it can't be obtained. It is the caller's responsibility to - CGContextRelease the context when finished using it. - - \warning This function is only available on \macos. - \warning This function is duplicated in the Cocoa platform plugin. -*/ - -CGContextRef qt_mac_cg_context(const QPaintDevice *pdev) -{ - if (pdev->devType() == QInternal::Pixmap) { - const QPixmap *pm = static_cast(pdev); - CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev); - uint flags = kCGImageAlphaPremultipliedFirst; - flags |= kCGBitmapByteOrder32Host; - CGContextRef ret = 0; - - QPlatformPixmap *data = const_cast(pm)->data_ptr().data(); - if (data->classId() == QPlatformPixmap::RasterClass) { - QImage *image = data->buffer(); - ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(), - 8, image->bytesPerLine(), colorspace, flags); - } else { - qDebug("qt_mac_cg_context: Unsupported pixmap class"); - } - - CGContextTranslateCTM(ret, 0, pm->height()); - qreal devicePixelRatio = pdev->devicePixelRatioF(); - CGContextScaleCTM(ret, devicePixelRatio, devicePixelRatio); - CGContextScaleCTM(ret, 1, -1); - return ret; - } else if (pdev->devType() == QInternal::Widget) { - //CGContextRef ret = static_cast(static_cast(pdev)->macCGHandle()); - ///CGContextRetain(ret); - //return ret; - qDebug("qt_mac_cg_context: not implemented: Widget class"); - return 0; - } - return 0; -} - /* FontHash::FontHash() { -- cgit v1.2.3 From d58d7a5376ccee53544e5141e442350ba4ad8089 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 28 Aug 2016 19:23:45 +0200 Subject: Add QStringList::join(QLatin1String) overload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Costs only ~300B in text size in QtCore, which is roughly compensated by savings in other QtBase libraries, even without specifically porting users to QL1S. Of course, the raison d'être for this overload is avoiding the expensive QLatin1String -> QString conversion which, for small lists, can take up to 50% of the total runtime (assuming memory allocations dominate over scanning and copying the list). [ChangeLog][QtCore][QStringList] Added join(QLatin1String) overload. Change-Id: I91d7e1d4e2c76d6dc79f2b750cf8e256dd4e0ab6 Reviewed-by: Thiago Macieira --- src/corelib/tools/qstringlist.cpp | 40 ++++++++++++++++++---- src/corelib/tools/qstringlist.h | 7 ++++ .../corelib/tools/qstringlist/tst_qstringlist.cpp | 1 + 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp index eae9e0e5d9..a0b65ea554 100644 --- a/src/corelib/tools/qstringlist.cpp +++ b/src/corelib/tools/qstringlist.cpp @@ -447,6 +447,17 @@ void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegularEx #endif // QT_NO_REGULAREXPRESSION #endif // QT_BOOTSTRAPPED +static int accumulatedSize(const QStringList &list, int seplen) +{ + int result = 0; + if (!list.isEmpty()) { + for (const auto &e : list) + result += e.size() + seplen; + result -= seplen; + } + return result; +} + /*! \fn QString QStringList::join(const QString &separator) const @@ -464,15 +475,9 @@ void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegularEx */ QString QtPrivate::QStringList_join(const QStringList *that, const QChar *sep, int seplen) { - int totalLength = 0; + const int totalLength = accumulatedSize(*that, seplen); const int size = that->size(); - for (int i = 0; i < size; ++i) - totalLength += that->at(i).size(); - - if(size > 0) - totalLength += seplen * (size - 1); - QString res; if (totalLength == 0) return res; @@ -485,6 +490,27 @@ QString QtPrivate::QStringList_join(const QStringList *that, const QChar *sep, i return res; } +/*! + \fn QString QStringList::join(QLatin1String separator) const + \since 5.8 + \overload join() +*/ +QString QtPrivate::QStringList_join(const QStringList &list, QLatin1String sep) +{ + QString result; + if (!list.isEmpty()) { + result.reserve(accumulatedSize(list, sep.size())); + const auto end = list.end(); + auto it = list.begin(); + result += *it; + while (++it != end) { + result += sep; + result += *it; + } + } + return result; +} + /*! \fn QStringList QStringList::operator+(const QStringList &other) const diff --git a/src/corelib/tools/qstringlist.h b/src/corelib/tools/qstringlist.h index 87f15528bf..720d7d7419 100644 --- a/src/corelib/tools/qstringlist.h +++ b/src/corelib/tools/qstringlist.h @@ -73,6 +73,7 @@ public: inline int removeDuplicates(); inline QString join(const QString &sep) const; + inline QString join(QLatin1String sep) const; inline QString join(QChar sep) const; inline QStringList filter(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; @@ -159,6 +160,7 @@ namespace QtPrivate { void Q_CORE_EXPORT QStringList_sort(QStringList *that, Qt::CaseSensitivity cs); int Q_CORE_EXPORT QStringList_removeDuplicates(QStringList *that); QString Q_CORE_EXPORT QStringList_join(const QStringList *that, const QChar *sep, int seplen); + Q_CORE_EXPORT QString QStringList_join(const QStringList &list, QLatin1String sep); QStringList Q_CORE_EXPORT QStringList_filter(const QStringList *that, const QString &str, Qt::CaseSensitivity cs); @@ -200,6 +202,11 @@ inline QString QListSpecialMethods::join(const QString &sep) const return QtPrivate::QStringList_join(self(), sep.constData(), sep.length()); } +QString QListSpecialMethods::join(QLatin1String sep) const +{ + return QtPrivate::QStringList_join(*self(), sep); +} + inline QString QListSpecialMethods::join(QChar sep) const { return QtPrivate::QStringList_join(self(), &sep, 1); diff --git a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp index 0fdafd9b01..2385aa992c 100644 --- a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp +++ b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp @@ -341,6 +341,7 @@ void tst_QStringList::join() const QFETCH(QString, expectedResult); QCOMPARE(input.join(separator), expectedResult); + QCOMPARE(input.join(QLatin1String(separator.toLatin1())), expectedResult); } void tst_QStringList::join_data() const -- cgit v1.2.3 From e419403ebf98c6c0524d4db664caca36052c1fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 13 Sep 2016 11:44:34 +0200 Subject: macOS: Remove unused function qt_mac_QRegionToHIMutableShape Code using it was removed in a198ce8d. Change-Id: I841f55768da080fbc87e0f2d9394cdc0a22e500e Reviewed-by: Jake Petroules --- src/plugins/platforms/cocoa/qcocoahelpers.h | 3 --- src/plugins/platforms/cocoa/qcocoahelpers.mm | 10 ---------- 2 files changed, 13 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index 272b443b68..7ce2d1a7ae 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -83,9 +83,6 @@ QColor qt_mac_toQColor(CGColorRef color); QBrush qt_mac_toQBrush(CGColorRef color); QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup = QPalette::Normal); -// Creates a mutable shape, it's the caller's responsibility to release. -HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion ®ion); - OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage); NSDragOperation qt_mac_mapDropAction(Qt::DropAction action); diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 21ffd8599f..c73587a821 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -158,16 +158,6 @@ NSImage *qt_mac_create_nsimage(const QIcon &icon) return nsImage; } -HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion ®ion) -{ - HIMutableShapeRef shape = HIShapeCreateMutable(); - for (const QRect &rect : region) { - CGRect cgRect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); - HIShapeUnionWithRect(shape, &cgRect); - } - return shape; -} - QColor qt_mac_toQColor(const NSColor *color) { QColor qtColor; -- cgit v1.2.3 From 49b3510bb929f37f1c549f25e999c42521f9a5fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 13 Sep 2016 14:08:27 +0200 Subject: macOS: Move image conversion functions to QtGui Change-Id: I911f2648e506f27519e98be1bffe2c5ab0f388f1 Reviewed-by: Jake Petroules --- src/gui/painting/qcoregraphics.mm | 145 ++++++++++++++++++++- src/gui/painting/qcoregraphics_p.h | 14 ++ src/plugins/platforms/cocoa/qcocoacursor.mm | 1 + src/plugins/platforms/cocoa/qcocoadrag.mm | 1 + src/plugins/platforms/cocoa/qcocoahelpers.h | 10 -- src/plugins/platforms/cocoa/qcocoahelpers.mm | 130 ------------------ src/plugins/platforms/cocoa/qcocoamenuitem.mm | 1 + src/plugins/platforms/cocoa/qcocoamimetypes.mm | 1 + .../platforms/cocoa/qcocoanativeinterface.mm | 2 + .../platforms/cocoa/qcocoasystemsettings.mm | 1 + .../platforms/cocoa/qcocoasystemtrayicon.mm | 1 + src/plugins/platforms/cocoa/qcocoawindow.mm | 1 + src/plugins/platforms/cocoa/qnsview.mm | 1 + 13 files changed, 168 insertions(+), 141 deletions(-) diff --git a/src/gui/painting/qcoregraphics.mm b/src/gui/painting/qcoregraphics.mm index fa5c9b61b2..cf668947ef 100644 --- a/src/gui/painting/qcoregraphics.mm +++ b/src/gui/painting/qcoregraphics.mm @@ -35,13 +35,156 @@ #include #include - +#include #include #include #include QT_BEGIN_NAMESPACE +// ---------------------- Images ---------------------- + +CGImageRef qt_mac_toCGImage(const QImage &inImage) +{ + CGImageRef cgImage = inImage.toCGImage(); + if (cgImage) + return cgImage; + + // Convert image data to a known-good format if the fast conversion fails. + return inImage.convertToFormat(QImage::Format_ARGB32_Premultiplied).toCGImage(); +} + +CGImageRef qt_mac_toCGImageMask(const QImage &image) +{ + static const auto deleter = [](void *image, const void *, size_t) { delete static_cast(image); }; + QCFType dataProvider = + CGDataProviderCreateWithData(new QImage(image), image.bits(), + image.byteCount(), deleter); + + return CGImageMaskCreate(image.width(), image.height(), 8, image.depth(), + image.bytesPerLine(), dataProvider, NULL, false); +} + +OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage) +{ + // Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev) + OSStatus err = noErr; + +#ifdef Q_OS_MACOS + require_action(inContext != NULL, InvalidContext, err = paramErr); + require_action(inBounds != NULL, InvalidBounds, err = paramErr); + require_action(inImage != NULL, InvalidImage, err = paramErr); +#endif + + CGContextSaveGState( inContext ); + CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds)); + CGContextScaleCTM(inContext, 1, -1); + + CGContextDrawImage(inContext, *inBounds, inImage); + + CGContextRestoreGState(inContext); + +#ifdef Q_OS_MACOS +InvalidImage: +InvalidBounds: +InvalidContext: +#endif + return err; +} + +QImage qt_mac_toQImage(CGImageRef image) +{ + const size_t w = CGImageGetWidth(image), + h = CGImageGetHeight(image); + QImage ret(w, h, QImage::Format_ARGB32_Premultiplied); + ret.fill(Qt::transparent); + CGRect rect = CGRectMake(0, 0, w, h); + QMacCGContext ctx(&ret); + qt_mac_drawCGImage(ctx, &rect, image); + return ret; +} + +#ifdef Q_OS_MACOS + +QT_END_NAMESPACE + +@interface NSGraphicsContext (QtAdditions) + ++ (NSGraphicsContext *)qt_graphicsContextWithCGContext:(CGContextRef)graphicsPort flipped:(BOOL)initialFlippedState; + +@end + +@implementation NSGraphicsContext (QtAdditions) + ++ (NSGraphicsContext *)qt_graphicsContextWithCGContext:(CGContextRef)graphicsPort flipped:(BOOL)initialFlippedState +{ +#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_10, __IPHONE_NA) + if (QT_PREPEND_NAMESPACE(QSysInfo::MacintoshVersion) >= QT_PREPEND_NAMESPACE(QSysInfo::MV_10_10)) + return [self graphicsContextWithCGContext:graphicsPort flipped:initialFlippedState]; +#endif + return [self graphicsContextWithGraphicsPort:graphicsPort flipped:initialFlippedState]; +} + +@end + +QT_BEGIN_NAMESPACE + +static NSImage *qt_mac_cgimage_to_nsimage(CGImageRef image) +{ + NSImage *newImage = [[NSImage alloc] initWithCGImage:image size:NSZeroSize]; + return newImage; +} + +NSImage *qt_mac_create_nsimage(const QPixmap &pm) +{ + if (pm.isNull()) + return 0; + QImage image = pm.toImage(); + CGImageRef cgImage = qt_mac_toCGImage(image); + NSImage *nsImage = qt_mac_cgimage_to_nsimage(cgImage); + CGImageRelease(cgImage); + return nsImage; +} + +NSImage *qt_mac_create_nsimage(const QIcon &icon) +{ + if (icon.isNull()) + return nil; + + NSImage *nsImage = [[NSImage alloc] init]; + foreach (QSize size, icon.availableSizes()) { + QPixmap pm = icon.pixmap(size); + QImage image = pm.toImage(); + CGImageRef cgImage = qt_mac_toCGImage(image); + NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage]; + [nsImage addRepresentation:imageRep]; + [imageRep release]; + CGImageRelease(cgImage); + } + return nsImage; +} + +QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size) +{ + const NSSize pixmapSize = NSMakeSize(size.width(), size.height()); + QPixmap pixmap(pixmapSize.width, pixmapSize.height); + pixmap.fill(Qt::transparent); + [image setSize:pixmapSize]; + const NSRect iconRect = NSMakeRect(0, 0, pixmapSize.width, pixmapSize.height); + QMacCGContext ctx(&pixmap); + if (!ctx) + return QPixmap(); + NSGraphicsContext *gc = [NSGraphicsContext qt_graphicsContextWithCGContext:ctx flipped:YES]; + if (!gc) + return QPixmap(); + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:gc]; + [image drawInRect:iconRect fromRect:iconRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil]; + [NSGraphicsContext restoreGraphicsState]; + return pixmap; +} + +#endif // Q_OS_MACOS // ---------------------- Color Management ---------------------- diff --git a/src/gui/painting/qcoregraphics_p.h b/src/gui/painting/qcoregraphics_p.h index b6ea5474ec..b2b29ecf76 100644 --- a/src/gui/painting/qcoregraphics_p.h +++ b/src/gui/painting/qcoregraphics_p.h @@ -49,9 +49,23 @@ #include #include +#ifdef Q_OS_MACOS +#include +#endif QT_BEGIN_NAMESPACE +#ifdef Q_OS_MACOS +Q_GUI_EXPORT NSImage *qt_mac_create_nsimage(const QPixmap &pm); +Q_GUI_EXPORT NSImage *qt_mac_create_nsimage(const QIcon &icon); +Q_GUI_EXPORT QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size); +#endif +Q_GUI_EXPORT CGImageRef qt_mac_toCGImage(const QImage &qImage); +Q_GUI_EXPORT CGImageRef qt_mac_toCGImageMask(const QImage &qImage); +Q_GUI_EXPORT QImage qt_mac_toQImage(CGImageRef image); + +Q_GUI_EXPORT OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage); + Q_GUI_EXPORT CGColorSpaceRef qt_mac_genericColorSpace(); Q_GUI_EXPORT CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice); diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm index 0433084436..8e523dfbbf 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.mm +++ b/src/plugins/platforms/cocoa/qcocoacursor.mm @@ -40,6 +40,7 @@ #include "qcocoacursor.h" #include "qcocoawindow.h" #include "qcocoahelpers.h" +#include #include diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm index 13ae0382ab..7d11023b78 100644 --- a/src/plugins/platforms/cocoa/qcocoadrag.mm +++ b/src/plugins/platforms/cocoa/qcocoadrag.mm @@ -43,6 +43,7 @@ #ifndef QT_NO_WIDGETS #include #endif +#include QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index 7ce2d1a7ae..c50b9fc972 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -69,22 +69,12 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list); inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qstrlist) { return reinterpret_cast(qt_mac_QStringListToNSMutableArrayVoid(qstrlist)); } -NSImage *qt_mac_cgimage_to_nsimage(CGImageRef iamge); -NSImage *qt_mac_create_nsimage(const QPixmap &pm); -NSImage *qt_mac_create_nsimage(const QIcon &icon); -CGImageRef qt_mac_toCGImage(const QImage &qImage); -CGImageRef qt_mac_toCGImageMask(const QImage &qImage); -QImage qt_mac_toQImage(CGImageRef image); -QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size); - QColor qt_mac_toQColor(const NSColor *color); QColor qt_mac_toQColor(CGColorRef color); QBrush qt_mac_toQBrush(CGColorRef color); QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup = QPalette::Normal); -OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage); - NSDragOperation qt_mac_mapDropAction(Qt::DropAction action); NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions); Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions); diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index c73587a821..a1566f4011 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -57,25 +57,6 @@ #include -@interface NSGraphicsContext (QtAdditions) - -+ (NSGraphicsContext *)qt_graphicsContextWithCGContext:(CGContextRef)graphicsPort flipped:(BOOL)initialFlippedState; - -@end - -@implementation NSGraphicsContext (QtAdditions) - -+ (NSGraphicsContext *)qt_graphicsContextWithCGContext:(CGContextRef)graphicsPort flipped:(BOOL)initialFlippedState -{ -#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_10, __IPHONE_NA) - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_10) - return [self graphicsContextWithCGContext:graphicsPort flipped:initialFlippedState]; -#endif - return [self graphicsContextWithGraphicsPort:graphicsPort flipped:initialFlippedState]; -} - -@end - QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQpaCocoaWindow, "qt.qpa.cocoa.window"); @@ -102,62 +83,6 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list) return result; } -CGImageRef qt_mac_toCGImage(const QImage &inImage) -{ - CGImageRef cgImage = inImage.toCGImage(); - if (cgImage) - return cgImage; - - // Convert image data to a known-good format if the fast conversion fails. - return inImage.convertToFormat(QImage::Format_ARGB32_Premultiplied).toCGImage(); -} - -CGImageRef qt_mac_toCGImageMask(const QImage &image) -{ - static const auto deleter = [](void *image, const void *, size_t) { delete static_cast(image); }; - QCFType dataProvider = - CGDataProviderCreateWithData(new QImage(image), image.bits(), - image.byteCount(), deleter); - - return CGImageMaskCreate(image.width(), image.height(), 8, image.depth(), - image.bytesPerLine(), dataProvider, NULL, false); -} - -NSImage *qt_mac_cgimage_to_nsimage(CGImageRef image) -{ - NSImage *newImage = [[NSImage alloc] initWithCGImage:image size:NSZeroSize]; - return newImage; -} - -NSImage *qt_mac_create_nsimage(const QPixmap &pm) -{ - if (pm.isNull()) - return 0; - QImage image = pm.toImage(); - CGImageRef cgImage = qt_mac_toCGImage(image); - NSImage *nsImage = qt_mac_cgimage_to_nsimage(cgImage); - CGImageRelease(cgImage); - return nsImage; -} - -NSImage *qt_mac_create_nsimage(const QIcon &icon) -{ - if (icon.isNull()) - return nil; - - NSImage *nsImage = [[NSImage alloc] init]; - foreach (QSize size, icon.availableSizes()) { - QPixmap pm = icon.pixmap(size); - QImage image = pm.toImage(); - CGImageRef cgImage = qt_mac_toCGImage(image); - NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage]; - [nsImage addRepresentation:imageRep]; - [imageRep release]; - CGImageRelease(cgImage); - } - return nsImage; -} - QColor qt_mac_toQColor(const NSColor *color) { QColor qtColor; @@ -457,28 +382,6 @@ NSRect qt_mac_flipRect(const QRect &rect) return NSMakeRect(rect.x(), flippedY, rect.width(), rect.height()); } -OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage) -{ - // Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev) - OSStatus err = noErr; - - require_action(inContext != NULL, InvalidContext, err = paramErr); - require_action(inBounds != NULL, InvalidBounds, err = paramErr); - require_action(inImage != NULL, InvalidImage, err = paramErr); - - CGContextSaveGState( inContext ); - CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds)); - CGContextScaleCTM(inContext, 1, -1); - - CGContextDrawImage(inContext, *inBounds, inImage); - - CGContextRestoreGState(inContext); -InvalidImage: -InvalidBounds: -InvalidContext: - return err; -} - Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum) { if (buttonNum == 0) @@ -499,37 +402,4 @@ QString qt_mac_removeAmpersandEscapes(QString s) return QPlatformTheme::removeMnemonics(s).trimmed(); } -QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size) -{ - const NSSize pixmapSize = NSMakeSize(size.width(), size.height()); - QPixmap pixmap(pixmapSize.width, pixmapSize.height); - pixmap.fill(Qt::transparent); - [image setSize:pixmapSize]; - const NSRect iconRect = NSMakeRect(0, 0, pixmapSize.width, pixmapSize.height); - QMacCGContext ctx(&pixmap); - if (!ctx) - return QPixmap(); - NSGraphicsContext *gc = [NSGraphicsContext qt_graphicsContextWithCGContext:ctx flipped:YES]; - if (!gc) - return QPixmap(); - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext setCurrentContext:gc]; - [image drawInRect:iconRect fromRect:iconRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil]; - [NSGraphicsContext restoreGraphicsState]; - return pixmap; -} - -QImage qt_mac_toQImage(CGImageRef image) -{ - const size_t w = CGImageGetWidth(image), - h = CGImageGetHeight(image); - QImage ret(w, h, QImage::Format_ARGB32_Premultiplied); - ret.fill(Qt::transparent); - CGRect rect = CGRectMake(0, 0, w, h); - QMacCGContext ctx(&ret); - qt_mac_drawCGImage(ctx, &rect, image); - return ret; -} - - QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index cac166a409..ea094c86ee 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -48,6 +48,7 @@ #include "qt_mac_p.h" #include "qcocoaapplication.h" // for custom application category #include "qcocoamenuloader.h" +#include #include diff --git a/src/plugins/platforms/cocoa/qcocoamimetypes.mm b/src/plugins/platforms/cocoa/qcocoamimetypes.mm index e7a3aab845..c109eb7bf4 100644 --- a/src/plugins/platforms/cocoa/qcocoamimetypes.mm +++ b/src/plugins/platforms/cocoa/qcocoamimetypes.mm @@ -40,6 +40,7 @@ #include "qcocoamimetypes.h" #include #include "qcocoahelpers.h" +#include QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index 8562246817..3ff37a8463 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -64,6 +64,8 @@ #include #endif +#include + #include #include diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm index be5fa61b8b..9ddad7fc7a 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm @@ -43,6 +43,7 @@ #include #include +#include #include diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm index 0640faeb8a..9a543e893e 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm @@ -86,6 +86,7 @@ #include "qt_mac_p.h" #include "qcocoahelpers.h" +#include #import diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 7fb695630b..b2fd0580bc 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -52,6 +52,7 @@ #include #include #include +#include #include diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index af324c07ff..3d30aca7e7 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -52,6 +52,7 @@ #include #include #include +#include #include "qcocoabackingstore.h" #ifndef QT_NO_OPENGL #include "qcocoaglcontext.h" -- cgit v1.2.3 From 5ad8b3aa32f7a085a97cbe95060551dff8ac726f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 13 Sep 2016 12:15:49 +0200 Subject: macOS: Move QColor/QBrush conversion functions to QtGui Change-Id: I971d1d69b491532fd0dc0bab72b274dec6591e6b Reviewed-by: Jake Petroules --- src/gui/painting/qcoregraphics.mm | 133 +++++++++++++++++++++++++++ src/gui/painting/qcoregraphics_p.h | 8 ++ src/plugins/platforms/cocoa/qcocoahelpers.h | 6 -- src/plugins/platforms/cocoa/qcocoahelpers.mm | 126 ------------------------- 4 files changed, 141 insertions(+), 132 deletions(-) diff --git a/src/gui/painting/qcoregraphics.mm b/src/gui/painting/qcoregraphics.mm index cf668947ef..6af12c19d8 100644 --- a/src/gui/painting/qcoregraphics.mm +++ b/src/gui/painting/qcoregraphics.mm @@ -186,6 +186,139 @@ QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size) #endif // Q_OS_MACOS +// ---------------------- Colors and Brushes ---------------------- + +QColor qt_mac_toQColor(CGColorRef color) +{ + QColor qtColor; + CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(color)); + const CGFloat *components = CGColorGetComponents(color); + if (model == kCGColorSpaceModelRGB) { + qtColor.setRgbF(components[0], components[1], components[2], components[3]); + } else if (model == kCGColorSpaceModelCMYK) { + qtColor.setCmykF(components[0], components[1], components[2], components[3]); + } else if (model == kCGColorSpaceModelMonochrome) { + qtColor.setRgbF(components[0], components[0], components[0], components[1]); + } else { + // Colorspace we can't deal with. + qWarning("Qt: qt_mac_toQColor: cannot convert from colorspace model: %d", model); + Q_ASSERT(false); + } + return qtColor; +} + +#ifdef Q_OS_MACOS +QColor qt_mac_toQColor(const NSColor *color) +{ + QColor qtColor; + NSString *colorSpace = [color colorSpaceName]; + if (colorSpace == NSDeviceCMYKColorSpace) { + CGFloat cyan, magenta, yellow, black, alpha; + [color getCyan:&cyan magenta:&magenta yellow:&yellow black:&black alpha:&alpha]; + qtColor.setCmykF(cyan, magenta, yellow, black, alpha); + } else { + NSColor *tmpColor; + tmpColor = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace]; + CGFloat red, green, blue, alpha; + [tmpColor getRed:&red green:&green blue:&blue alpha:&alpha]; + qtColor.setRgbF(red, green, blue, alpha); + } + return qtColor; +} +#endif + +QBrush qt_mac_toQBrush(CGColorRef color) +{ + QBrush qtBrush; + CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(color)); + if (model == kCGColorSpaceModelPattern) { + // Colorspace we can't deal with; the color is drawn directly using a callback. + qWarning("Qt: qt_mac_toQBrush: cannot convert from colorspace model: %d", model); + Q_ASSERT(false); + } else { + qtBrush.setStyle(Qt::SolidPattern); + qtBrush.setColor(qt_mac_toQColor(color)); + } + return qtBrush; +} + +#ifdef Q_OS_MACOS +static bool qt_mac_isSystemColorOrInstance(const NSColor *color, NSString *colorNameComponent, NSString *className) +{ + // We specifically do not want isKindOfClass: here + if ([color.className isEqualToString:className]) // NSPatternColorSpace + return true; + if ([color.catalogNameComponent isEqualToString:@"System"] && + [color.colorNameComponent isEqualToString:colorNameComponent] && + [color.colorSpaceName isEqualToString:NSNamedColorSpace]) + return true; + return false; +} + +QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup) +{ + QBrush qtBrush; + + // QTBUG-49773: This calls NSDrawMenuItemBackground to render a 1 by n gradient; could use HITheme + if ([color.className isEqualToString:@"NSMenuItemHighlightColor"]) { + qWarning("Qt: qt_mac_toQBrush: cannot convert from NSMenuItemHighlightColor"); + return qtBrush; + } + + // Not a catalog color or a manifestation of System.windowBackgroundColor; + // only retrieved from NSWindow.backgroundColor directly + if ([color.className isEqualToString:@"NSMetalPatternColor"]) { + // NSTexturedBackgroundWindowMask, could theoretically handle this without private API by + // creating a window with the appropriate properties and then calling NSWindow.backgroundColor.patternImage, + // which returns a texture sized 1 by (window height, including frame), backed by a CGPattern + // which follows the window key state... probably need to allow QBrush to store a function pointer + // like CGPattern does + qWarning("Qt: qt_mac_toQBrush: cannot convert from NSMetalPatternColor"); + return qtBrush; + } + + // No public API to get these colors/stops; + // both accurately obtained through runtime object inspection on OS X 10.11 + // (the NSColor object has NSGradient i-vars for both color groups) + if (qt_mac_isSystemColorOrInstance(color, @"_sourceListBackgroundColor", @"NSSourceListBackgroundColor")) { + QLinearGradient gradient; + if (colorGroup == QPalette::Active) { + gradient.setColorAt(0, QColor(233, 237, 242)); + gradient.setColorAt(0.5, QColor(225, 229, 235)); + gradient.setColorAt(1, QColor(209, 216, 224)); + } else { + gradient.setColorAt(0, QColor(248, 248, 248)); + gradient.setColorAt(0.5, QColor(240, 240, 240)); + gradient.setColorAt(1, QColor(235, 235, 235)); + } + return QBrush(gradient); + } + + // A couple colors are special... they are actually instances of NSGradientPatternColor, which + // override set/setFill/setStroke to instead initialize an internal color + // ([NSColor colorWithCalibratedWhite:0.909804 alpha:1.000000]) while still returning the + // ruled lines pattern image (from OS X 10.4) to the user from -[NSColor patternImage] + // (and providing no public API to get the underlying color without this insanity) + if (qt_mac_isSystemColorOrInstance(color, @"controlColor", @"NSGradientPatternColor") || + qt_mac_isSystemColorOrInstance(color, @"windowBackgroundColor", @"NSGradientPatternColor")) { + qtBrush.setStyle(Qt::SolidPattern); + qtBrush.setColor(qt_mac_toQColor(color.CGColor)); + return qtBrush; + } + + if (NSColor *patternColor = [color colorUsingColorSpaceName:NSPatternColorSpace]) { + NSImage *patternImage = patternColor.patternImage; + const QSizeF sz(patternImage.size.width, patternImage.size.height); + // FIXME: QBrush is not resolution independent (QTBUG-49774) + qtBrush.setTexture(qt_mac_toQPixmap(patternImage, sz)); + } else { + qtBrush.setStyle(Qt::SolidPattern); + qtBrush.setColor(qt_mac_toQColor(color)); + } + return qtBrush; +} +#endif + // ---------------------- Color Management ---------------------- static CGColorSpaceRef m_genericColorSpace = 0; diff --git a/src/gui/painting/qcoregraphics_p.h b/src/gui/painting/qcoregraphics_p.h index b2b29ecf76..ab2579387e 100644 --- a/src/gui/painting/qcoregraphics_p.h +++ b/src/gui/painting/qcoregraphics_p.h @@ -47,6 +47,7 @@ #include #include +#include #include #ifdef Q_OS_MACOS @@ -71,6 +72,13 @@ Q_GUI_EXPORT CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice * Q_GUI_EXPORT void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform); +#ifdef Q_OS_MACOS +Q_GUI_EXPORT QColor qt_mac_toQColor(const NSColor *color); +Q_GUI_EXPORT QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup = QPalette::Normal); +#endif +Q_GUI_EXPORT QColor qt_mac_toQColor(CGColorRef color); +Q_GUI_EXPORT QBrush qt_mac_toQBrush(CGColorRef color); + class Q_GUI_EXPORT QMacCGContext { public: diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index c50b9fc972..536a2d2d58 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -69,12 +69,6 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list); inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qstrlist) { return reinterpret_cast(qt_mac_QStringListToNSMutableArrayVoid(qstrlist)); } -QColor qt_mac_toQColor(const NSColor *color); -QColor qt_mac_toQColor(CGColorRef color); - -QBrush qt_mac_toQBrush(CGColorRef color); -QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup = QPalette::Normal); - NSDragOperation qt_mac_mapDropAction(Qt::DropAction action); NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions); Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions); diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index a1566f4011..0c7c30579e 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -83,132 +83,6 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list) return result; } -QColor qt_mac_toQColor(const NSColor *color) -{ - QColor qtColor; - NSString *colorSpace = [color colorSpaceName]; - if (colorSpace == NSDeviceCMYKColorSpace) { - CGFloat cyan, magenta, yellow, black, alpha; - [color getCyan:&cyan magenta:&magenta yellow:&yellow black:&black alpha:&alpha]; - qtColor.setCmykF(cyan, magenta, yellow, black, alpha); - } else { - NSColor *tmpColor; - tmpColor = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace]; - CGFloat red, green, blue, alpha; - [tmpColor getRed:&red green:&green blue:&blue alpha:&alpha]; - qtColor.setRgbF(red, green, blue, alpha); - } - return qtColor; -} - -QColor qt_mac_toQColor(CGColorRef color) -{ - QColor qtColor; - CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(color)); - const CGFloat *components = CGColorGetComponents(color); - if (model == kCGColorSpaceModelRGB) { - qtColor.setRgbF(components[0], components[1], components[2], components[3]); - } else if (model == kCGColorSpaceModelCMYK) { - qtColor.setCmykF(components[0], components[1], components[2], components[3]); - } else if (model == kCGColorSpaceModelMonochrome) { - qtColor.setRgbF(components[0], components[0], components[0], components[1]); - } else { - // Colorspace we can't deal with. - qWarning("Qt: qt_mac_toQColor: cannot convert from colorspace model: %d", model); - Q_ASSERT(false); - } - return qtColor; -} - -QBrush qt_mac_toQBrush(CGColorRef color) -{ - QBrush qtBrush; - CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(color)); - if (model == kCGColorSpaceModelPattern) { - // Colorspace we can't deal with; the color is drawn directly using a callback. - qWarning("Qt: qt_mac_toQBrush: cannot convert from colorspace model: %d", model); - Q_ASSERT(false); - } else { - qtBrush.setStyle(Qt::SolidPattern); - qtBrush.setColor(qt_mac_toQColor(color)); - } - return qtBrush; -} - -static bool qt_mac_isSystemColorOrInstance(const NSColor *color, NSString *colorNameComponent, NSString *className) -{ - // We specifically do not want isKindOfClass: here - if ([color.className isEqualToString:className]) // NSPatternColorSpace - return true; - if ([color.catalogNameComponent isEqualToString:@"System"] && - [color.colorNameComponent isEqualToString:colorNameComponent] && - [color.colorSpaceName isEqualToString:NSNamedColorSpace]) - return true; - return false; -} - -QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup) -{ - QBrush qtBrush; - - // QTBUG-49773: This calls NSDrawMenuItemBackground to render a 1 by n gradient; could use HITheme - if ([color.className isEqualToString:@"NSMenuItemHighlightColor"]) { - qWarning("Qt: qt_mac_toQBrush: cannot convert from NSMenuItemHighlightColor"); - return qtBrush; - } - - // Not a catalog color or a manifestation of System.windowBackgroundColor; - // only retrieved from NSWindow.backgroundColor directly - if ([color.className isEqualToString:@"NSMetalPatternColor"]) { - // NSTexturedBackgroundWindowMask, could theoretically handle this without private API by - // creating a window with the appropriate properties and then calling NSWindow.backgroundColor.patternImage, - // which returns a texture sized 1 by (window height, including frame), backed by a CGPattern - // which follows the window key state... probably need to allow QBrush to store a function pointer - // like CGPattern does - qWarning("Qt: qt_mac_toQBrush: cannot convert from NSMetalPatternColor"); - return qtBrush; - } - - // No public API to get these colors/stops; - // both accurately obtained through runtime object inspection on OS X 10.11 - // (the NSColor object has NSGradient i-vars for both color groups) - if (qt_mac_isSystemColorOrInstance(color, @"_sourceListBackgroundColor", @"NSSourceListBackgroundColor")) { - QLinearGradient gradient; - if (colorGroup == QPalette::Active) { - gradient.setColorAt(0, QColor(233, 237, 242)); - gradient.setColorAt(0.5, QColor(225, 229, 235)); - gradient.setColorAt(1, QColor(209, 216, 224)); - } else { - gradient.setColorAt(0, QColor(248, 248, 248)); - gradient.setColorAt(0.5, QColor(240, 240, 240)); - gradient.setColorAt(1, QColor(235, 235, 235)); - } - return QBrush(gradient); - } - - // A couple colors are special... they are actually instances of NSGradientPatternColor, which - // override set/setFill/setStroke to instead initialize an internal color - // ([NSColor colorWithCalibratedWhite:0.909804 alpha:1.000000]) while still returning the - // ruled lines pattern image (from OS X 10.4) to the user from -[NSColor patternImage] - // (and providing no public API to get the underlying color without this insanity) - if (qt_mac_isSystemColorOrInstance(color, @"controlColor", @"NSGradientPatternColor") || - qt_mac_isSystemColorOrInstance(color, @"windowBackgroundColor", @"NSGradientPatternColor")) { - qtBrush.setStyle(Qt::SolidPattern); - qtBrush.setColor(qt_mac_toQColor(color.CGColor)); - return qtBrush; - } - - if (NSColor *patternColor = [color colorUsingColorSpaceName:NSPatternColorSpace]) { - NSImage *patternImage = patternColor.patternImage; - const QSizeF sz(patternImage.size.width, patternImage.size.height); - qtBrush.setTexture(qt_mac_toQPixmap(patternImage, sz)); // QTBUG-49774 - } else { - qtBrush.setStyle(Qt::SolidPattern); - qtBrush.setColor(qt_mac_toQColor(color)); - } - return qtBrush; -} - struct dndenum_mapper { NSDragOperation mac_code; -- cgit v1.2.3 From dc3af6a164f82c1f9fadf86e910656504ccc48e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 16 Dec 2015 15:27:21 +0100 Subject: iOS: Implement support for QScreen::grabWindow() Only windows that are part of the application can be grabbed. This excludes the system statusbar and other system overlays, as well as windows of other applications. This is a limitation due to the security model of iOS. There exists APIs to grab a snapshot of the complete screen, but these APIs return a view that can be used as a placeholder e.g. during view transformations, and doesn't match our API that require reading of pixels. Task-number: QTBUG-49944 Change-Id: I8fd5b4c2777be1486f0ff22762d5e9b64c927e70 Reviewed-by: Jake Petroules --- src/gui/kernel/qscreen.cpp | 4 ++++ src/plugins/platforms/ios/qiosscreen.h | 2 ++ src/plugins/platforms/ios/qiosscreen.mm | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp index bc4a25a65f..1dd8fb5e67 100644 --- a/src/gui/kernel/qscreen.cpp +++ b/src/gui/kernel/qscreen.cpp @@ -667,6 +667,10 @@ void QScreenPrivate::updatePrimaryOrientation() that are not part of the application, window system frames, and so on. + \warning Grabbing windows that are not part of the application is + not supported on systems such as iOS, where sandboxing/security + prevents reading pixels of windows not owned by the application. + The grabWindow() function grabs pixels from the screen, not from the window, i.e. if there is another window partially or entirely over the one you grab, you get pixels from the overlying window, diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index cc83e7f3d2..9fcce42825 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -68,6 +68,8 @@ public: Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE; void setOrientationUpdateMask(Qt::ScreenOrientations mask) Q_DECL_OVERRIDE; + QPixmap grabWindow(WId window, int x, int y, int width, int height) const override; + UIScreen *uiScreen() const; UIWindow *uiWindow() const; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index b9c77e9bba..bd2aa0e7e7 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -47,6 +47,7 @@ #include "quiview.h" #include +#include #include @@ -457,6 +458,38 @@ void QIOSScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) } } +QPixmap QIOSScreen::grabWindow(WId window, int x, int y, int width, int height) const +{ + if (window && ![reinterpret_cast(window) isKindOfClass:[UIView class]]) + return QPixmap(); + + UIView *view = window ? reinterpret_cast(window) : m_uiWindow; + + if (width < 0) + width = qMax(view.bounds.size.width - x, CGFloat(0)); + if (height < 0) + height = qMax(view.bounds.size.height - y, CGFloat(0)); + + CGRect captureRect = [m_uiWindow convertRect:CGRectMake(x, y, width, height) fromView:view]; + captureRect = CGRectIntersection(captureRect, m_uiWindow.bounds); + + UIGraphicsBeginImageContextWithOptions(captureRect.size, NO, 0.0); + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextTranslateCTM(context, -captureRect.origin.x, -captureRect.origin.y); + + // Draws the complete view hierarchy of m_uiWindow into the given rect, which + // needs to be the same aspect ratio as the m_uiWindow's size. Since we've + // translated the graphics context, and are potentially drawing into a smaller + // context than the full window, the resulting image will be a subsection of the + // full screen. + [m_uiWindow drawViewHierarchyInRect:m_uiWindow.bounds afterScreenUpdates:NO]; + + UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return QPixmap::fromImage(qt_mac_toQImage(screenshot.CGImage)); +} + UIScreen *QIOSScreen::uiScreen() const { return m_uiScreen; -- cgit v1.2.3 From 41ab34d9e8b30190dc5aef672625902611663ce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 14 Sep 2016 14:29:26 +0200 Subject: =?UTF-8?q?Blacklist=20modalWindowModallity=20on=20macOS=20aka=20?= =?UTF-8?q?=E2=80=9Cosx=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Passes locally, unstable on CI. Change-Id: I251ad9603d14fd6195f721135ac606a1fd6b5060 Reviewed-by: Tor Arne Vestbø --- tests/auto/gui/kernel/qwindow/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST index 81ab693ee7..19d9262bca 100644 --- a/tests/auto/gui/kernel/qwindow/BLACKLIST +++ b/tests/auto/gui/kernel/qwindow/BLACKLIST @@ -14,3 +14,5 @@ ubuntu-14.04 ubuntu-16.04 [modalDialogClosingOneOfTwoModal] osx +[modalWindowModallity] +osx -- cgit v1.2.3 From 2d2d90781abdcdbd2a98201877563c83d926dd1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 8 Sep 2016 23:08:29 +0200 Subject: macOS: Implement QCocoaBackingStore in terms of QRasterBackingStore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous detection of device pixel ratio changes in paintDevice() is not needed, as QBackingStore::beginPaint() already does this check and calls resize(). Change-Id: I9ee8410fa3a5404c5ec19d2cba4543a9e3359fe9 Reviewed-by: Morten Johan Sørvig --- .../graphics/qrasterbackingstore.cpp | 13 +++- .../graphics/qrasterbackingstore_p.h | 9 ++- src/platformsupport/platformsupport.pro | 2 +- src/plugins/platforms/cocoa/qcocoabackingstore.h | 21 ++----- src/plugins/platforms/cocoa/qcocoabackingstore.mm | 72 ++++------------------ src/plugins/platforms/cocoa/qnsview.mm | 4 +- 6 files changed, 35 insertions(+), 86 deletions(-) diff --git a/src/platformsupport/graphics/qrasterbackingstore.cpp b/src/platformsupport/graphics/qrasterbackingstore.cpp index 58e811dff1..325c98b93d 100644 --- a/src/platformsupport/graphics/qrasterbackingstore.cpp +++ b/src/platformsupport/graphics/qrasterbackingstore.cpp @@ -62,13 +62,20 @@ void QRasterBackingStore::resize(const QSize &size, const QRegion &staticContent if (m_image.size() == effectiveBufferSize) return; - QImage::Format format = window()->format().hasAlpha() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; - m_image = QImage(effectiveBufferSize, format); + m_image = QImage(effectiveBufferSize, format()); m_image.setDevicePixelRatio(windowDevicePixelRatio); - if (format == QImage::Format_ARGB32_Premultiplied) + if (m_image.format() == QImage::Format_ARGB32_Premultiplied) m_image.fill(Qt::transparent); } +QImage::Format QRasterBackingStore::format() const +{ + if (window()->format().hasAlpha()) + return QImage::Format_ARGB32_Premultiplied; + else + return QImage::Format_RGB32; +} + QPaintDevice *QRasterBackingStore::paintDevice() { return &m_image; diff --git a/src/platformsupport/graphics/qrasterbackingstore_p.h b/src/platformsupport/graphics/qrasterbackingstore_p.h index de96c99b5a..55976d2ceb 100644 --- a/src/platformsupport/graphics/qrasterbackingstore_p.h +++ b/src/platformsupport/graphics/qrasterbackingstore_p.h @@ -62,13 +62,16 @@ public: QRasterBackingStore(QWindow *window); ~QRasterBackingStore(); - QPaintDevice *paintDevice() Q_DECL_OVERRIDE; - QImage toImage() const Q_DECL_OVERRIDE; - void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE; + void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE; bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE; void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE; + QPaintDevice *paintDevice() Q_DECL_OVERRIDE; + QImage toImage() const Q_DECL_OVERRIDE; + protected: + virtual QImage::Format format() const; + QImage m_image; }; diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro index 15bbaf94c9..19efa60f48 100644 --- a/src/platformsupport/platformsupport.pro +++ b/src/platformsupport/platformsupport.pro @@ -29,6 +29,6 @@ unix:!darwin:qtConfig(dbus) { include(dbusmenu/dbusmenu.pri) include(dbustray/dbustray.pri) } -uikit: include(graphics/graphics.pri) +darwin: include(graphics/graphics.pri) load(qt_module) diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h index 52a3e756b9..562be2be8f 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.h +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h @@ -40,33 +40,20 @@ #ifndef QBACKINGSTORE_COCOA_H #define QBACKINGSTORE_COCOA_H -#include - -#include "qcocoawindow.h" -#include "qnsview.h" - -#include +#include QT_BEGIN_NAMESPACE -class QCocoaBackingStore : public QPlatformBackingStore +class QCocoaBackingStore : public QRasterBackingStore { public: QCocoaBackingStore(QWindow *window); ~QCocoaBackingStore(); - QPaintDevice *paintDevice() Q_DECL_OVERRIDE; - void flush(QWindow *widget, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; - QImage toImage() const Q_DECL_OVERRIDE; - - void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE; - bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE; - void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE; - qreal getBackingStoreDevicePixelRatio(); + void flush(QWindow *, const QRegion &, const QPoint &) Q_DECL_OVERRIDE; private: - QImage m_qImage; - QSize m_requestedSize; + QImage::Format format() const Q_DECL_OVERRIDE; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index 20233518b3..af5418315c 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -38,13 +38,13 @@ ****************************************************************************/ #include "qcocoabackingstore.h" -#include -#include "qcocoahelpers.h" + +#include "qcocoawindow.h" QT_BEGIN_NAMESPACE QCocoaBackingStore::QCocoaBackingStore(QWindow *window) - : QPlatformBackingStore(window) + : QRasterBackingStore(window) { } @@ -54,69 +54,21 @@ QCocoaBackingStore::~QCocoaBackingStore() [cocoaWindow->m_qtView clearBackingStore:this]; } -QPaintDevice *QCocoaBackingStore::paintDevice() -{ - QCocoaWindow *cocoaWindow = static_cast(window()->handle()); - int windowDevicePixelRatio = int(cocoaWindow->devicePixelRatio()); - - // Receate the backing store buffer if the effective buffer size has changed, - // either due to a window resize or devicePixelRatio change. - QSize effectiveBufferSize = m_requestedSize * windowDevicePixelRatio; - if (m_qImage.size() != effectiveBufferSize) { - QImage::Format format = (window()->format().hasAlpha() || cocoaWindow->m_drawContentBorderGradient) - ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; - m_qImage = QImage(effectiveBufferSize, format); - m_qImage.setDevicePixelRatio(windowDevicePixelRatio); - if (format == QImage::Format_ARGB32_Premultiplied) - m_qImage.fill(Qt::transparent); - } - return &m_qImage; -} - -void QCocoaBackingStore::flush(QWindow *win, const QRegion ®ion, const QPoint &offset) +QImage::Format QCocoaBackingStore::format() const { - if (!m_qImage.isNull()) { - if (QCocoaWindow *cocoaWindow = static_cast(win->handle())) - [cocoaWindow->m_qtView flushBackingStore:this region:region offset:offset]; - } -} + if (static_cast(window()->handle())->m_drawContentBorderGradient) + return QImage::Format_ARGB32_Premultiplied; -QImage QCocoaBackingStore::toImage() const -{ - return m_qImage; + return QRasterBackingStore::format(); } -void QCocoaBackingStore::resize(const QSize &size, const QRegion &) +void QCocoaBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) { - m_requestedSize = size; -} + if (m_image.isNull()) + return; -bool QCocoaBackingStore::scroll(const QRegion &area, int dx, int dy) -{ - extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset); - const qreal devicePixelRatio = m_qImage.devicePixelRatio(); - QPoint qpoint(dx * devicePixelRatio, dy * devicePixelRatio); - for (const QRect &rect : area) { - const QRect qrect(rect.topLeft() * devicePixelRatio, rect.size() * devicePixelRatio); - qt_scrollRectInImage(m_qImage, qrect, qpoint); - } - return true; -} - -void QCocoaBackingStore::beginPaint(const QRegion ®ion) -{ - if (m_qImage.hasAlphaChannel()) { - QPainter p(&m_qImage); - p.setCompositionMode(QPainter::CompositionMode_Source); - const QColor blank = Qt::transparent; - for (const QRect &rect : region) - p.fillRect(rect, blank); - } -} - -qreal QCocoaBackingStore::getBackingStoreDevicePixelRatio() -{ - return m_qImage.devicePixelRatio(); + if (QCocoaWindow *cocoaWindow = static_cast(window->handle())) + [cocoaWindow->m_qtView flushBackingStore:this region:region offset:offset]; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 3d30aca7e7..22a32c7ceb 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -495,7 +495,7 @@ static bool _q_dontOverrideCtrlLMB = false; qCDebug(lcQpaCocoaWindow) << "[QNSView flushBackingStore:]" << m_window << region.rectCount() << region.boundingRect() << offset; m_backingStore = backingStore; - m_backingStoreOffset = offset * m_backingStore->getBackingStoreDevicePixelRatio(); + m_backingStoreOffset = offset * m_backingStore->paintDevice()->devicePixelRatio(); for (const QRect &rect : region) [self setNeedsDisplayInRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())]; } @@ -577,7 +577,7 @@ static bool _q_dontOverrideCtrlLMB = false; // The backing store source rect will be larger on retina displays. // Scale dirtyRect by the device pixel ratio: - const qreal devicePixelRatio = m_backingStore->getBackingStoreDevicePixelRatio(); + const qreal devicePixelRatio = m_backingStore->paintDevice()->devicePixelRatio(); CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * devicePixelRatio, dirtyRect.origin.y * devicePixelRatio, dirtyRect.size.width * devicePixelRatio, -- cgit v1.2.3 From 8b2f91e32860243f8d635a3e94e53cc6afe6def3 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 6 Sep 2016 11:12:30 +0200 Subject: Add AVX2 versions of the fast blending functions This patch adds AVX2 versions of the fast blending functions that we already have SSE2 versions of. Change-Id: Ifd1a22f7891b6208cb74929ad26095d12c5a1efb Reviewed-by: Thiago Macieira --- src/corelib/tools/qsimd_p.h | 3 + src/gui/painting/qdrawhelper.cpp | 42 ++++- src/gui/painting/qdrawhelper_avx2.cpp | 305 +++++++++++++++++++++++++++++++++- 3 files changed, 340 insertions(+), 10 deletions(-) diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index 9d8695c0f6..2fd4be00a5 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -468,6 +468,9 @@ static inline quint64 qCpuFeatures() #define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length) \ for (; i < static_cast(qMin(static_cast(length), ((4 - ((reinterpret_cast(ptr) >> 2) & 0x3)) & 0x3))); ++i) +#define ALIGNMENT_PROLOGUE_32BYTES(ptr, i, length) \ + for (; i < static_cast(qMin(static_cast(length), ((8 - ((reinterpret_cast(ptr) >> 2) & 0x7)) & 0x7))); ++i) + QT_END_NAMESPACE #endif // QSIMD_P_H diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index c697aceaf3..ea0c5bbb88 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6548,6 +6548,15 @@ static void qInitDrawhelperFunctions() qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2; + extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha); + extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha); + extern void QT_FASTCALL comp_func_Source_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha); + extern void QT_FASTCALL comp_func_Plus_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha); + qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_sse2; + qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_sse2; + qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_sse2; + qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2; + #ifdef QT_COMPILER_SUPPORTS_SSSE3 if (qCpuHasFeature(SSSE3)) { extern void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl, @@ -6592,24 +6601,39 @@ static void qInitDrawhelperFunctions() } #endif -#if defined(QT_COMPILER_SUPPORTS_AVX2) && !defined(__AVX2__) +#if defined(QT_COMPILER_SUPPORTS_AVX2) if (qCpuHasFeature(AVX2)) { +#if !defined(__AVX2__) extern const uint *QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, const uint *src, int count, const QVector *, QDitherInfo *); extern const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, const uint *src, int count, const QVector *, QDitherInfo *); qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_avx2; qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_avx2; +#endif + extern void qt_blend_rgb32_on_rgb32_avx2(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, int const_alpha); + extern void qt_blend_argb32_on_argb32_avx2(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, int const_alpha); + qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx2; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx2; + qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx2; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx2; + qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx2; + qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx2; + qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx2; + qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx2; + + extern void QT_FASTCALL comp_func_SourceOver_avx2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha); + extern void QT_FASTCALL comp_func_solid_SourceOver_avx2(uint *destPixels, int length, uint color, uint const_alpha); + extern void QT_FASTCALL comp_func_Source_avx2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha); + qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_avx2; + qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_avx2; + qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_avx2; } #endif - extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha); - extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha); - extern void QT_FASTCALL comp_func_Source_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha); - extern void QT_FASTCALL comp_func_Plus_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha); - qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_sse2; - qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_sse2; - qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_sse2; - qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2; #endif // SSE2 diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp index 35a975c972..01ffd54918 100644 --- a/src/gui/painting/qdrawhelper_avx2.cpp +++ b/src/gui/painting/qdrawhelper_avx2.cpp @@ -37,12 +37,14 @@ ** ****************************************************************************/ -#include +#include "qdrawhelper_p.h" +#include "qdrawingprimitive_sse2_p.h" #if defined(QT_COMPILER_SUPPORTS_AVX2) QT_BEGIN_NAMESPACE +// Autovectorized premultiply functions: const uint *QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, const uint *src, int count, const QVector *, QDitherInfo *) { @@ -55,6 +57,307 @@ const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, const uint return qt_convertRGBA8888ToARGB32PM(buffer, src, count); } +// Vectorized blend functions: + +// See BYTE_MUL_SSE2 for details. +inline static void BYTE_MUL_AVX2(__m256i &pixelVector, const __m256i &alphaChannel, const __m256i &colorMask, const __m256i &half) +{ + __m256i pixelVectorAG = _mm256_srli_epi16(pixelVector, 8); + __m256i pixelVectorRB = _mm256_and_si256(pixelVector, colorMask); + + pixelVectorAG = _mm256_mullo_epi16(pixelVectorAG, alphaChannel); + pixelVectorRB = _mm256_mullo_epi16(pixelVectorRB, alphaChannel); + + pixelVectorRB = _mm256_add_epi16(pixelVectorRB, _mm256_srli_epi16(pixelVectorRB, 8)); + pixelVectorAG = _mm256_add_epi16(pixelVectorAG, _mm256_srli_epi16(pixelVectorAG, 8)); + pixelVectorRB = _mm256_add_epi16(pixelVectorRB, half); + pixelVectorAG = _mm256_add_epi16(pixelVectorAG, half); + + pixelVectorRB = _mm256_srli_epi16(pixelVectorRB, 8); + pixelVectorAG = _mm256_andnot_si256(colorMask, pixelVectorAG); + + pixelVector = _mm256_or_si256(pixelVectorAG, pixelVectorRB); +} + +// See INTERPOLATE_PIXEL_255_SSE2 for details. +inline static void INTERPOLATE_PIXEL_255_AVX2(const __m256i &srcVector, __m256i &dstVector, const __m256i &alphaChannel, const __m256i &oneMinusAlphaChannel, const __m256i &colorMask, const __m256i &half) +{ + const __m256i srcVectorAG = _mm256_srli_epi16(srcVector, 8); + const __m256i dstVectorAG = _mm256_srli_epi16(dstVector, 8); + const __m256i srcVectorRB = _mm256_and_si256(srcVector, colorMask); + const __m256i dstVectorRB = _mm256_and_si256(dstVector, colorMask); + const __m256i srcVectorAGalpha = _mm256_mullo_epi16(srcVectorAG, alphaChannel); + const __m256i srcVectorRBalpha = _mm256_mullo_epi16(srcVectorRB, alphaChannel); + const __m256i dstVectorAGoneMinusAlpha = _mm256_mullo_epi16(dstVectorAG, oneMinusAlphaChannel); + const __m256i dstVectorRBoneMinusAlpha = _mm256_mullo_epi16(dstVectorRB, oneMinusAlphaChannel); + __m256i finalAG = _mm256_add_epi16(srcVectorAGalpha, dstVectorAGoneMinusAlpha); + __m256i finalRB = _mm256_add_epi16(srcVectorRBalpha, dstVectorRBoneMinusAlpha); + finalAG = _mm256_add_epi16(finalAG, _mm256_srli_epi16(finalAG, 8)); + finalRB = _mm256_add_epi16(finalRB, _mm256_srli_epi16(finalRB, 8)); + finalAG = _mm256_add_epi16(finalAG, half); + finalRB = _mm256_add_epi16(finalRB, half); + finalAG = _mm256_andnot_si256(colorMask, finalAG); + finalRB = _mm256_srli_epi16(finalRB, 8); + + dstVector = _mm256_or_si256(finalAG, finalRB); +} + +// See BLEND_SOURCE_OVER_ARGB32_SSE2 for details. +inline static void BLEND_SOURCE_OVER_ARGB32_AVX2(quint32 *dst, const quint32 *src, const int length) +{ + const __m256i half = _mm256_set1_epi16(0x80); + const __m256i one = _mm256_set1_epi16(0xff); + const __m256i colorMask = _mm256_set1_epi32(0x00ff00ff); + const __m256i alphaMask = _mm256_set1_epi32(0xff000000); + const __m256i offsetMask = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7); + const __m256i alphaShuffleMask = _mm256_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3, + char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3); + + const int minusOffsetToAlignDstOn32Bytes = (reinterpret_cast(dst) >> 2) & 0x7; + + int x = 0; + // Prologue to handle all pixels until dst is 32-byte aligned in one step. + if (minusOffsetToAlignDstOn32Bytes != 0 && x < (length - 7)) { + const __m256i prologueMask = _mm256_sub_epi32(_mm256_set1_epi32(minusOffsetToAlignDstOn32Bytes - 1), offsetMask); + const __m256i srcVector = _mm256_maskload_epi32((const int *)&src[x - minusOffsetToAlignDstOn32Bytes], prologueMask); + const __m256i prologueAlphaMask = _mm256_blendv_epi8(_mm256_setzero_si256(), alphaMask, prologueMask); + if (!_mm256_testz_si256(srcVector, prologueAlphaMask)) { + if (_mm256_testc_si256(srcVector, prologueAlphaMask)) { + _mm256_maskstore_epi32((int *)&dst[x - minusOffsetToAlignDstOn32Bytes], prologueMask, srcVector); + } else { + __m256i alphaChannel = _mm256_shuffle_epi8(srcVector, alphaShuffleMask); + alphaChannel = _mm256_sub_epi16(one, alphaChannel); + __m256i dstVector = _mm256_maskload_epi32((int *)&dst[x - minusOffsetToAlignDstOn32Bytes], prologueMask); + BYTE_MUL_AVX2(dstVector, alphaChannel, colorMask, half); + dstVector = _mm256_add_epi8(dstVector, srcVector); + _mm256_maskstore_epi32((int *)&dst[x - minusOffsetToAlignDstOn32Bytes], prologueMask, dstVector); + } + } + x += (8 - minusOffsetToAlignDstOn32Bytes); + } + + for (; x < (length - 7); x += 8) { + const __m256i srcVector = _mm256_lddqu_si256((const __m256i *)&src[x]); + if (!_mm256_testz_si256(srcVector, alphaMask)) { + if (_mm256_testc_si256(srcVector, alphaMask)) { + _mm256_store_si256((__m256i *)&dst[x], srcVector); + } else { + __m256i alphaChannel = _mm256_shuffle_epi8(srcVector, alphaShuffleMask); + alphaChannel = _mm256_sub_epi16(one, alphaChannel); + __m256i dstVector = _mm256_load_si256((__m256i *)&dst[x]); + BYTE_MUL_AVX2(dstVector, alphaChannel, colorMask, half); + dstVector = _mm256_add_epi8(dstVector, srcVector); + _mm256_store_si256((__m256i *)&dst[x], dstVector); + } + } + } + + // Epilogue to handle all remaining pixels in one step. + if (x < length) { + const __m256i epilogueMask = _mm256_add_epi32(offsetMask, _mm256_set1_epi32(x - length)); + const __m256i srcVector = _mm256_maskload_epi32((const int *)&src[x], epilogueMask); + const __m256i epilogueAlphaMask = _mm256_blendv_epi8(_mm256_setzero_si256(), alphaMask, epilogueMask); + if (!_mm256_testz_si256(srcVector, epilogueAlphaMask)) { + if (_mm256_testc_si256(srcVector, epilogueAlphaMask)) { + _mm256_maskstore_epi32((int *)&dst[x], epilogueMask, srcVector); + } else { + __m256i alphaChannel = _mm256_shuffle_epi8(srcVector, alphaShuffleMask); + alphaChannel = _mm256_sub_epi16(one, alphaChannel); + __m256i dstVector = _mm256_maskload_epi32((int *)&dst[x], epilogueMask); + BYTE_MUL_AVX2(dstVector, alphaChannel, colorMask, half); + dstVector = _mm256_add_epi8(dstVector, srcVector); + _mm256_maskstore_epi32((int *)&dst[x], epilogueMask, dstVector); + } + } + } +} + + +// See BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_SSE2 for details. +inline static void BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_AVX2(quint32 *dst, const quint32 *src, const int length, const int const_alpha) +{ + int x = 0; + + ALIGNMENT_PROLOGUE_32BYTES(dst, x, length) + blend_pixel(dst[x], src[x], const_alpha); + + const __m256i half = _mm256_set1_epi16(0x80); + const __m256i one = _mm256_set1_epi16(0xff); + const __m256i colorMask = _mm256_set1_epi32(0x00ff00ff); + const __m256i alphaMask = _mm256_set1_epi32(0xff000000); + const __m256i alphaShuffleMask = _mm256_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3, + char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3); + const __m256i constAlphaVector = _mm256_set1_epi16(const_alpha); + for (; x < (length - 7); x += 8) { + __m256i srcVector = _mm256_lddqu_si256((const __m256i *)&src[x]); + if (!_mm256_testz_si256(srcVector, alphaMask)) { + BYTE_MUL_AVX2(srcVector, constAlphaVector, colorMask, half); + + __m256i alphaChannel = _mm256_shuffle_epi8(srcVector, alphaShuffleMask); + alphaChannel = _mm256_sub_epi16(one, alphaChannel); + __m256i dstVector = _mm256_load_si256((__m256i *)&dst[x]); + BYTE_MUL_AVX2(dstVector, alphaChannel, colorMask, half); + dstVector = _mm256_add_epi8(dstVector, srcVector); + _mm256_store_si256((__m256i *)&dst[x], dstVector); + } + } + for (; x < length; ++x) + blend_pixel(dst[x], src[x], const_alpha); +} + +void qt_blend_argb32_on_argb32_avx2(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha) +{ + if (const_alpha == 256) { + for (int y = 0; y < h; ++y) { + const quint32 *src = reinterpret_cast(srcPixels); + quint32 *dst = reinterpret_cast(destPixels); + BLEND_SOURCE_OVER_ARGB32_AVX2(dst, src, w); + destPixels += dbpl; + srcPixels += sbpl; + } + } else if (const_alpha != 0) { + const_alpha = (const_alpha * 255) >> 8; + for (int y = 0; y < h; ++y) { + const quint32 *src = reinterpret_cast(srcPixels); + quint32 *dst = reinterpret_cast(destPixels); + BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_AVX2(dst, src, w, const_alpha); + destPixels += dbpl; + srcPixels += sbpl; + } + } +} + +void qt_blend_rgb32_on_rgb32_avx2(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha) +{ + if (const_alpha == 256) { + for (int y = 0; y < h; ++y) { + const quint32 *src = reinterpret_cast(srcPixels); + quint32 *dst = reinterpret_cast(destPixels); + ::memcpy(dst, src, w * sizeof(uint)); + srcPixels += sbpl; + destPixels += dbpl; + } + return; + } + if (const_alpha == 0) + return; + + const __m256i half = _mm256_set1_epi16(0x80); + const __m256i colorMask = _mm256_set1_epi32(0x00ff00ff); + + const_alpha = (const_alpha * 255) >> 8; + int one_minus_const_alpha = 255 - const_alpha; + const __m256i constAlphaVector = _mm256_set1_epi16(const_alpha); + const __m256i oneMinusConstAlpha = _mm256_set1_epi16(one_minus_const_alpha); + for (int y = 0; y < h; ++y) { + const quint32 *src = reinterpret_cast(srcPixels); + quint32 *dst = reinterpret_cast(destPixels); + int x = 0; + + // First, align dest to 32 bytes: + ALIGNMENT_PROLOGUE_32BYTES(dst, x, w) + dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha); + + // 2) interpolate pixels with AVX2 + for (; x < (w - 7); x += 8) { + const __m256i srcVector = _mm256_lddqu_si256((const __m256i *)&src[x]); + if (!_mm256_testc_si256(srcVector, _mm256_setzero_si256())) { + __m256i dstVector = _mm256_load_si256((__m256i *)&dst[x]); + INTERPOLATE_PIXEL_255_AVX2(srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half); + _mm256_store_si256((__m256i *)&dst[x], dstVector); + } + } + + // 3) Epilogue + for (; x < w; ++x) + dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha); + + srcPixels += sbpl; + destPixels += dbpl; + } +} + +void QT_FASTCALL comp_func_SourceOver_avx2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha) +{ + Q_ASSERT(const_alpha < 256); + + const quint32 *src = (const quint32 *) srcPixels; + quint32 *dst = (quint32 *) destPixels; + + if (const_alpha == 255) + BLEND_SOURCE_OVER_ARGB32_AVX2(dst, src, length); + else + BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_AVX2(dst, src, length, const_alpha); +} + +void QT_FASTCALL comp_func_Source_avx2(uint *dst, const uint *src, int length, uint const_alpha) +{ + if (const_alpha == 255) { + ::memcpy(dst, src, length * sizeof(uint)); + } else { + const int ialpha = 255 - const_alpha; + + int x = 0; + + // 1) prologue, align on 32 bytes + ALIGNMENT_PROLOGUE_32BYTES(dst, x, length) + dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], ialpha); + + // 2) interpolate pixels with AVX2 + const __m256i half = _mm256_set1_epi16(0x80); + const __m256i colorMask = _mm256_set1_epi32(0x00ff00ff); + const __m256i constAlphaVector = _mm256_set1_epi16(const_alpha); + const __m256i oneMinusConstAlpha = _mm256_set1_epi16(ialpha); + for (; x < length - 7; x += 8) { + const __m256i srcVector = _mm256_lddqu_si256((const __m256i *)&src[x]); + __m256i dstVector = _mm256_load_si256((__m256i *)&dst[x]); + INTERPOLATE_PIXEL_255_AVX2(srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half); + _mm256_store_si256((__m256i *)&dst[x], dstVector); + } + + // 3) Epilogue + for (; x < length; ++x) + dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], ialpha); + } +} + +void QT_FASTCALL comp_func_solid_SourceOver_avx2(uint *destPixels, int length, uint color, uint const_alpha) +{ + if ((const_alpha & qAlpha(color)) == 255) { + qt_memfill32(destPixels, color, length); + } else { + if (const_alpha != 255) + color = BYTE_MUL(color, const_alpha); + + const quint32 minusAlphaOfColor = qAlpha(~color); + int x = 0; + + quint32 *dst = (quint32 *) destPixels; + const __m256i colorVector = _mm256_set1_epi32(color); + const __m256i colorMask = _mm256_set1_epi32(0x00ff00ff); + const __m256i half = _mm256_set1_epi16(0x80); + const __m256i minusAlphaOfColorVector = _mm256_set1_epi16(minusAlphaOfColor); + + ALIGNMENT_PROLOGUE_32BYTES(dst, x, length) + destPixels[x] = color + BYTE_MUL(destPixels[x], minusAlphaOfColor); + + for (; x < length - 7; x += 8) { + __m256i dstVector = _mm256_load_si256((__m256i *)&dst[x]); + BYTE_MUL_AVX2(dstVector, minusAlphaOfColorVector, colorMask, half); + dstVector = _mm256_add_epi8(colorVector, dstVector); + _mm256_store_si256((__m256i *)&dst[x], dstVector); + } + for (; x < length; ++x) + destPixels[x] = color + BYTE_MUL(destPixels[x], minusAlphaOfColor); + } +} + QT_END_NAMESPACE #endif -- cgit v1.2.3 From 04cb6e2754529d503050ec5841e23c273afaae96 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Sun, 18 Sep 2016 18:40:13 -0700 Subject: Fix namespaced build on iOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I682fabe8891e0325e6545b4499a59af4ad584c41 Reviewed-by: Mike Krus Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosbackingstore.mm | 2 ++ src/plugins/platforms/ios/qioscontext.mm | 3 +++ src/plugins/platforms/ios/qiosfiledialog.h | 4 ++-- src/plugins/platforms/ios/qiosglobal.h | 4 ++++ src/plugins/platforms/ios/qiosglobal.mm | 4 ++++ src/plugins/platforms/ios/qiosinputcontext.h | 4 ++-- src/plugins/platforms/ios/qiosinputcontext.mm | 8 ++++++-- src/plugins/platforms/ios/qiosmessagedialog.h | 4 ++-- src/plugins/platforms/ios/qiosplatformaccessibility.mm | 2 +- src/plugins/platforms/ios/qiosscreen.mm | 2 ++ src/plugins/platforms/ios/qiostextresponder.h | 10 +++++++--- src/plugins/platforms/ios/qiostextresponder.mm | 2 +- src/plugins/platforms/ios/qiosviewcontroller.h | 7 ++++++- src/plugins/platforms/ios/qiosviewcontroller.mm | 6 +++--- src/plugins/platforms/ios/qioswindow.h | 4 ++-- src/plugins/platforms/ios/qioswindow.mm | 2 ++ src/plugins/platforms/ios/quiaccessibilityelement.mm | 2 +- src/plugins/platforms/ios/quiview.h | 8 ++++++-- src/plugins/platforms/ios/quiview.mm | 4 ++-- 19 files changed, 58 insertions(+), 24 deletions(-) diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index fb0c9805f9..357a3db3c9 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -49,6 +49,8 @@ #include +QT_BEGIN_NAMESPACE + class QIOSPaintDevice : public QOpenGLPaintDevice { public: diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index 50374dc951..2d5286e971 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -48,6 +48,8 @@ #import #import +QT_BEGIN_NAMESPACE + Q_LOGGING_CATEGORY(lcQpaGLContext, "qt.qpa.glcontext"); QIOSContext::QIOSContext(QOpenGLContext *context) @@ -314,3 +316,4 @@ bool QIOSContext::isSharing() const #include "moc_qioscontext.cpp" +QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosfiledialog.h b/src/plugins/platforms/ios/qiosfiledialog.h index 855bab0424..7fe24eaefe 100644 --- a/src/plugins/platforms/ios/qiosfiledialog.h +++ b/src/plugins/platforms/ios/qiosfiledialog.h @@ -43,10 +43,10 @@ #include #include -QT_BEGIN_NAMESPACE - Q_FORWARD_DECLARE_OBJC_CLASS(UIViewController); +QT_BEGIN_NAMESPACE + class QIOSFileDialog : public QPlatformFileDialogHelper { public: diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 50bedd7b28..f74e3004cc 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -74,6 +74,8 @@ QT_END_NAMESPACE + (id)currentFirstResponder; @end +QT_BEGIN_NAMESPACE + class FirstResponderCandidate : public QScopedValueRollback { public: @@ -84,4 +86,6 @@ private: static UIResponder *s_firstResponderCandidate; }; +QT_END_NAMESPACE + #endif // QIOSGLOBAL_H diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 7ca3c66971..1482ffc7af 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -114,6 +114,8 @@ int infoPlistValue(NSString* key, int defaultValue) return value ? [value intValue] : defaultValue; } +QT_END_NAMESPACE + // ------------------------------------------------------------------------- @interface QtFirstResponderEvent : UIEvent @@ -164,6 +166,8 @@ int infoPlistValue(NSString* key, int defaultValue) } @end +QT_BEGIN_NAMESPACE + FirstResponderCandidate::FirstResponderCandidate(UIResponder *responder) : QScopedValueRollback(s_firstResponderCandidate, responder) { diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index 2b0643f26e..9fdf021d07 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -51,13 +51,13 @@ const char kImePlatformDataInputView[] = "inputView"; const char kImePlatformDataInputAccessoryView[] = "inputAccessoryView"; const char kImePlatformDataReturnKeyType[] = "returnKeyType"; -QT_BEGIN_NAMESPACE - @class QIOSLocaleListener; @class QIOSKeyboardListener; @class QIOSTextInputResponder; @protocol KeyboardState; +QT_BEGIN_NAMESPACE + struct KeyboardState { KeyboardState() : diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index c6cbb9b101..68088540c6 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -97,14 +97,14 @@ static QUIView *focusView() @interface QIOSKeyboardListener : UIGestureRecognizer { @private - QIOSInputContext *m_context; + QT_PREPEND_NAMESPACE(QIOSInputContext) *m_context; } @property BOOL hasDeferredScrollToCursor; @end @implementation QIOSKeyboardListener -- (id)initWithQIOSInputContext:(QIOSInputContext *)context +- (id)initWithQIOSInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)context { if (self = [super initWithTarget:self action:@selector(gestureStateChanged:)]) { @@ -291,6 +291,8 @@ static QUIView *focusView() // ------------------------------------------------------------------------- +QT_BEGIN_NAMESPACE + Qt::InputMethodQueries ImeState::update(Qt::InputMethodQueries properties) { if (!properties) @@ -713,3 +715,5 @@ QLocale QIOSInputContext::locale() const { return QLocale(QString::fromNSString([[NSLocale currentLocale] objectForKey:NSLocaleIdentifier])); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosmessagedialog.h b/src/plugins/platforms/ios/qiosmessagedialog.h index 971c8d8b4d..e67e10a5e1 100644 --- a/src/plugins/platforms/ios/qiosmessagedialog.h +++ b/src/plugins/platforms/ios/qiosmessagedialog.h @@ -43,11 +43,11 @@ #include #include -QT_BEGIN_NAMESPACE - Q_FORWARD_DECLARE_OBJC_CLASS(UIAlertController); Q_FORWARD_DECLARE_OBJC_CLASS(UIAlertAction); +QT_BEGIN_NAMESPACE + class QIOSMessageDialog : public QPlatformMessageDialogHelper { public: diff --git a/src/plugins/platforms/ios/qiosplatformaccessibility.mm b/src/plugins/platforms/ios/qiosplatformaccessibility.mm index bc51850760..aef4216e03 100644 --- a/src/plugins/platforms/ios/qiosplatformaccessibility.mm +++ b/src/plugins/platforms/ios/qiosplatformaccessibility.mm @@ -65,7 +65,7 @@ void invalidateCache(QAccessibleInterface *iface) // when items get added or removed from the screen foreach (QWindow *win, QGuiApplication::topLevelWindows()) { if (win && win->handle()) { - QIOSWindow *window = static_cast(win->handle()); + QT_PREPEND_NAMESPACE(QIOSWindow) *window = static_cast(win->handle()); window->clearAccessibleCache(); } } diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index bd2aa0e7e7..013061a6d2 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -176,6 +176,8 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) // ------------------------------------------------------------------------- +QT_BEGIN_NAMESPACE + /*! Returns the model identifier of the device. diff --git a/src/plugins/platforms/ios/qiostextresponder.h b/src/plugins/platforms/ios/qiostextresponder.h index f7450df4c8..77be2cf2fe 100644 --- a/src/plugins/platforms/ios/qiostextresponder.h +++ b/src/plugins/platforms/ios/qiostextresponder.h @@ -42,19 +42,23 @@ #include #include +QT_BEGIN_NAMESPACE + class QIOSInputContext; +QT_END_NAMESPACE + @interface QIOSTextInputResponder : UIResponder { @private - QIOSInputContext *m_inputContext; - QInputMethodQueryEvent *m_configuredImeState; + QT_PREPEND_NAMESPACE(QIOSInputContext) *m_inputContext; + QT_PREPEND_NAMESPACE(QInputMethodQueryEvent) *m_configuredImeState; QString m_markedText; BOOL m_inSendEventToFocusObject; BOOL m_inSelectionChange; } -- (id)initWithInputContext:(QIOSInputContext *)context; +- (id)initWithInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)context; - (BOOL)needsKeyboardReconfigure:(Qt::InputMethodQueries)updatedProperties; - (void)notifyInputDelegate:(Qt::InputMethodQueries)updatedProperties; diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index cd7945641e..3c95083e45 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -163,7 +163,7 @@ @implementation QIOSTextInputResponder -- (id)initWithInputContext:(QIOSInputContext *)inputContext +- (id)initWithInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)inputContext { if (!(self = [self init])) return self; diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h index 92c4e59d1a..f7b190ba22 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.h +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -38,12 +38,17 @@ ****************************************************************************/ #import +#include + +QT_BEGIN_NAMESPACE class QIOSScreen; +QT_END_NAMESPACE + @interface QIOSViewController : UIViewController -- (id)initWithQIOSScreen:(QIOSScreen *)screen; +- (id)initWithQIOSScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen; - (void)updateProperties; #ifndef Q_OS_TVOS diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index c8c07bd298..72eb5e27a0 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -58,7 +58,7 @@ @interface QIOSViewController () { @public - QPointer m_screen; + QPointer m_screen; BOOL m_updatingProperties; QMetaObject::Connection m_focusWindowChangeConnection; } @@ -126,7 +126,7 @@ { Q_UNUSED(subview); - QIOSScreen *screen = self.qtViewController->m_screen; + QT_PREPEND_NAMESPACE(QIOSScreen) *screen = self.qtViewController->m_screen; // The 'window' property of our view is not valid until the window // has been shown, so we have to access it through the QIOSScreen. @@ -229,7 +229,7 @@ @implementation QIOSViewController -- (id)initWithQIOSScreen:(QIOSScreen *)screen +- (id)initWithQIOSScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen { if (self = [self init]) { m_screen = screen; diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index afc2f0f89d..81fad420f6 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -48,10 +48,10 @@ class QIOSContext; class QIOSWindow; -QT_BEGIN_NAMESPACE - @class QUIView; +QT_BEGIN_NAMESPACE + class QIOSWindow : public QObject, public QPlatformWindow { Q_OBJECT diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index cddfbe6b06..ae14d87a30 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -54,6 +54,8 @@ #include +QT_BEGIN_NAMESPACE + QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[QUIView alloc] initWithQIOSWindow:this]) diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.mm b/src/plugins/platforms/ios/quiaccessibilityelement.mm index 105d7cd65f..a26ba61b3c 100644 --- a/src/plugins/platforms/ios/quiaccessibilityelement.mm +++ b/src/plugins/platforms/ios/quiaccessibilityelement.mm @@ -63,7 +63,7 @@ QAccessibleCache *cache = QAccessibleCache::instance(); - QMacAccessibilityElement *element = cache->elementForId(anId); + QT_MANGLE_NAMESPACE(QMacAccessibilityElement) *element = cache->elementForId(anId); if (!element) { Q_ASSERT(QAccessible::accessibleInterface(anId)); element = [[self alloc] initWithId:anId withAccessibilityContainer: view]; diff --git a/src/plugins/platforms/ios/quiview.h b/src/plugins/platforms/ios/quiview.h index fdaae943d8..1500f0b41c 100644 --- a/src/plugins/platforms/ios/quiview.h +++ b/src/plugins/platforms/ios/quiview.h @@ -44,14 +44,18 @@ #include +QT_BEGIN_NAMESPACE + class QIOSWindow; +QT_END_NAMESPACE + @class QIOSViewController; @interface QUIView : UIView { @public - QIOSWindow *m_qioswindow; + QT_PREPEND_NAMESPACE(QIOSWindow) *m_qioswindow; @private QHash m_activeTouches; int m_nextTouchId; @@ -60,7 +64,7 @@ class QIOSWindow; NSMutableArray *m_accessibleElements; }; -- (id)initWithQIOSWindow:(QIOSWindow *)window; +- (id)initWithQIOSWindow:(QT_PREPEND_NAMESPACE(QIOSWindow) *)window; - (void)sendUpdatedExposeEvent; - (BOOL)isActiveWindow; @end diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 2c32e56525..e039594406 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -59,7 +59,7 @@ return [CAEAGLLayer class]; } -- (id)initWithQIOSWindow:(QIOSWindow *)window +- (id)initWithQIOSWindow:(QT_PREPEND_NAMESPACE(QIOSWindow) *)window { if (self = [self initWithFrame:window->geometry().toCGRect()]) m_qioswindow = window; @@ -524,7 +524,7 @@ - (QWindow *)qwindow { if ([self isKindOfClass:[QUIView class]]) { - if (QIOSWindow *w = static_cast(self)->m_qioswindow) + if (QT_PREPEND_NAMESPACE(QIOSWindow) *w = static_cast(self)->m_qioswindow) return w->window(); } return nil; -- cgit v1.2.3 From e395e79145ff861b2dd87e404d229d769a19ab7e Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Tue, 20 Sep 2016 12:53:39 +0200 Subject: Fix QtNative.checkSelfPermission() Only return activity object when available and *not* when unavailable. Task-number: QTBUG-55035 Task-number: QTBUG-50759 Change-Id: I60b1be528b2e4a3d630f4085b7642d74e18482bd Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: BogDan Vatra --- src/android/jar/src/org/qtproject/qt5/android/QtNative.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index 6876aac11f..af4f20679c 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -456,7 +456,7 @@ public class QtNative } public static Context getContext() { - if (m_activity == null) + if (m_activity != null) return m_activity; return m_service; } -- cgit v1.2.3 From b598541bf37b2f9eb6fbd8f1f52fc5e98f1ebf2b Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 19 Sep 2016 11:36:59 +0200 Subject: Simplify source fetch qdrawhelper tables Collapse the tables that are mostly identical, to much shorter tables and a simple functions to make it easier to read and maintain. Change-Id: I44fdaebe9927b49a94385057756d9d87ad3c33f5 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/gui/painting/qdrawhelper.cpp | 641 ++++++++------------------------------- 1 file changed, 125 insertions(+), 516 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index ea0c5bbb88..c1a49b7d9a 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -3263,342 +3263,72 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co return buffer; } -static SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { - // Untransformed - { - 0, // Invalid - fetchUntransformed, // Mono - fetchUntransformed, // MonoLsb - fetchUntransformed, // Indexed8 - fetchUntransformedARGB32PM, // RGB32 - fetchUntransformed, // ARGB32 - fetchUntransformedARGB32PM, // ARGB32_Premultiplied - fetchUntransformedRGB16, // RGB16 - fetchUntransformed, // ARGB8565_Premultiplied - fetchUntransformed, // RGB666 - fetchUntransformed, // ARGB6666_Premultiplied - fetchUntransformed, // RGB555 - fetchUntransformed, // ARGB8555_Premultiplied - fetchUntransformed, // RGB888 - fetchUntransformed, // RGB444 - fetchUntransformed, // ARGB4444_Premultiplied - fetchUntransformed, // RGBX8888 - fetchUntransformed, // RGBA8888 - fetchUntransformed, // RGBA8888_Premultiplied - fetchUntransformed, // Format_BGR30 - fetchUntransformed, // Format_A2BGR30_Premultiplied - fetchUntransformed, // Format_RGB30 - fetchUntransformed, // Format_A2RGB30_Premultiplied - fetchUntransformed, // Alpha8 - fetchUntransformed, // Grayscale8 - }, - // Tiled - { - 0, // Invalid - fetchUntransformed, // Mono - fetchUntransformed, // MonoLsb - fetchUntransformed, // Indexed8 - fetchUntransformedARGB32PM, // RGB32 - fetchUntransformed, // ARGB32 - fetchUntransformedARGB32PM, // ARGB32_Premultiplied - fetchUntransformedRGB16, // RGB16 - fetchUntransformed, // ARGB8565_Premultiplied - fetchUntransformed, // RGB666 - fetchUntransformed, // ARGB6666_Premultiplied - fetchUntransformed, // RGB555 - fetchUntransformed, // ARGB8555_Premultiplied - fetchUntransformed, // RGB888 - fetchUntransformed, // RGB444 - fetchUntransformed, // ARGB4444_Premultiplied - fetchUntransformed, // RGBX8888 - fetchUntransformed, // RGBA8888 - fetchUntransformed, // RGBA8888_Premultiplied - fetchUntransformed, // BGR30 - fetchUntransformed, // A2BGR30_Premultiplied - fetchUntransformed, // RGB30 - fetchUntransformed, // A2RGB30_Premultiplied - fetchUntransformed, // Alpha8 - fetchUntransformed, // Grayscale8 - }, - // Transformed - { - 0, // Invalid - fetchTransformed, // Mono - fetchTransformed, // MonoLsb - fetchTransformed, // Indexed8 - fetchTransformedARGB32PM, // RGB32 - fetchTransformed, // ARGB32 - fetchTransformedARGB32PM, // ARGB32_Premultiplied - fetchTransformed, // RGB16 - fetchTransformed, // ARGB8565_Premultiplied - fetchTransformed, // RGB666 - fetchTransformed, // ARGB6666_Premultiplied - fetchTransformed, // RGB555 - fetchTransformed, // ARGB8555_Premultiplied - fetchTransformed, // RGB888 - fetchTransformed, // RGB444 - fetchTransformed, // ARGB4444_Premultiplied - fetchTransformed, // RGBX8888 - fetchTransformed, // RGBA8888 - fetchTransformed, // RGBA8888_Premultiplied - fetchTransformed, // BGR30 - fetchTransformed, // A2BGR30_Premultiplied - fetchTransformed, // RGB30 - fetchTransformed, // A2RGB30_Premultiplied - fetchTransformed, // Alpah8 - fetchTransformed, // Grayscale8 - }, - { - 0, // TransformedTiled - fetchTransformed, // Mono - fetchTransformed, // MonoLsb - fetchTransformed, // Indexed8 - fetchTransformedARGB32PM, // RGB32 - fetchTransformed, // ARGB32 - fetchTransformedARGB32PM, // ARGB32_Premultiplied - fetchTransformed, // RGB16 - fetchTransformed, // ARGB8565_Premultiplied - fetchTransformed, // RGB666 - fetchTransformed, // ARGB6666_Premultiplied - fetchTransformed, // RGB555 - fetchTransformed, // ARGB8555_Premultiplied - fetchTransformed, // RGB888 - fetchTransformed, // RGB444 - fetchTransformed, // ARGB4444_Premultiplied - fetchTransformed, // RGBX8888 - fetchTransformed, // RGBA8888 - fetchTransformed, // RGBA8888_Premultiplied - fetchTransformed, // BGR30 - fetchTransformed, // A2BGR30_Premultiplied - fetchTransformed, // RGB30 - fetchTransformed, // A2RGB30_Premultiplied - fetchTransformed, // Alpha8 - fetchTransformed, // Grayscale8 - }, - { - 0, // Bilinear - fetchTransformedBilinear, // Mono - fetchTransformedBilinear, // MonoLsb - fetchTransformedBilinear, // Indexed8 - fetchTransformedBilinearARGB32PM, // RGB32 - fetchTransformedBilinear, // ARGB32 - fetchTransformedBilinearARGB32PM, // ARGB32_Premultiplied - fetchTransformedBilinear, // RGB16 - fetchTransformedBilinear, // ARGB8565_Premultiplied - fetchTransformedBilinear, // RGB666 - fetchTransformedBilinear, // ARGB6666_Premultiplied - fetchTransformedBilinear, // RGB555 - fetchTransformedBilinear, // ARGB8555_Premultiplied - fetchTransformedBilinear, // RGB888 - fetchTransformedBilinear, // RGB444 - fetchTransformedBilinear, // ARGB4444_Premultiplied - fetchTransformedBilinear, // RGBX8888 - fetchTransformedBilinear, // RGBA8888 - fetchTransformedBilinear, // RGBA8888_Premultiplied - fetchTransformedBilinear, // BGR30 - fetchTransformedBilinear, // A2BGR30_Premultiplied - fetchTransformedBilinear, // RGB30 - fetchTransformedBilinear, // A2RGB30_Premultiplied - fetchTransformedBilinear, // Alpha8 - fetchTransformedBilinear, // Grayscale8 - }, - { - 0, // BilinearTiled - fetchTransformedBilinear, // Mono - fetchTransformedBilinear, // MonoLsb - fetchTransformedBilinear, // Indexed8 - fetchTransformedBilinearARGB32PM, // RGB32 - fetchTransformedBilinear, // ARGB32 - fetchTransformedBilinearARGB32PM, // ARGB32_Premultiplied - fetchTransformedBilinear, // RGB16 - fetchTransformedBilinear, // ARGB8565_Premultiplied - fetchTransformedBilinear, // RGB666 - fetchTransformedBilinear, // ARGB6666_Premultiplied - fetchTransformedBilinear, // RGB555 - fetchTransformedBilinear, // ARGB8555_Premultiplied - fetchTransformedBilinear, // RGB888 - fetchTransformedBilinear, // RGB444 - fetchTransformedBilinear, // ARGB4444_Premultiplied - fetchTransformedBilinear, // RGBX8888 - fetchTransformedBilinear, // RGBA8888 - fetchTransformedBilinear, // RGBA8888_Premultiplied - fetchTransformedBilinear, // BGR30 - fetchTransformedBilinear, // A2BGR30_Premultiplied - fetchTransformedBilinear, // RGB30 - fetchTransformedBilinear, // A2RGB30_Premultiplied - fetchTransformedBilinear, // Alpha8 - fetchTransformedBilinear, // Grayscale8 - }, +// FetchUntransformed can have more specialized methods added depending on SIMD features. +static SourceFetchProc sourceFetchUntransformed[QImage::NImageFormats] = { + 0, // Invalid + fetchUntransformed, // Mono + fetchUntransformed, // MonoLsb + fetchUntransformed, // Indexed8 + fetchUntransformedARGB32PM, // RGB32 + fetchUntransformed, // ARGB32 + fetchUntransformedARGB32PM, // ARGB32_Premultiplied + fetchUntransformedRGB16, // RGB16 + fetchUntransformed, // ARGB8565_Premultiplied + fetchUntransformed, // RGB666 + fetchUntransformed, // ARGB6666_Premultiplied + fetchUntransformed, // RGB555 + fetchUntransformed, // ARGB8555_Premultiplied + fetchUntransformed, // RGB888 + fetchUntransformed, // RGB444 + fetchUntransformed, // ARGB4444_Premultiplied + fetchUntransformed, // RGBX8888 + fetchUntransformed, // RGBA8888 + fetchUntransformed, // RGBA8888_Premultiplied + fetchUntransformed, // Format_BGR30 + fetchUntransformed, // Format_A2BGR30_Premultiplied + fetchUntransformed, // Format_RGB30 + fetchUntransformed, // Format_A2RGB30_Premultiplied + fetchUntransformed, // Alpha8 + fetchUntransformed, // Grayscale8 }; -static SourceFetchProc64 sourceFetch64[NBlendTypes][QImage::NImageFormats] = { - // Untransformed - { - 0, // Invalid - fetchUntransformed64, // Mono - fetchUntransformed64, // MonoLsb - fetchUntransformed64, // Indexed8 - fetchUntransformed64, // RGB32 - fetchUntransformed64, // ARGB32 - fetchUntransformed64, // ARGB32_Premultiplied - fetchUntransformed64, // RGB16 - fetchUntransformed64, // ARGB8565_Premultiplied - fetchUntransformed64, // RGB666 - fetchUntransformed64, // ARGB6666_Premultiplied - fetchUntransformed64, // RGB555 - fetchUntransformed64, // ARGB8555_Premultiplied - fetchUntransformed64, // RGB888 - fetchUntransformed64, // RGB444 - fetchUntransformed64, // ARGB4444_Premultiplied - fetchUntransformed64, // RGBX8888 - fetchUntransformed64, // RGBA8888 - fetchUntransformed64, // RGBA8888_Premultiplied - fetchUntransformed64, // Format_BGR30 - fetchUntransformed64, // Format_A2BGR30_Premultiplied - fetchUntransformed64, // Format_RGB30 - fetchUntransformed64, // Format_A2RGB30_Premultiplied - fetchUntransformed64, // Alpha8 - fetchUntransformed64, // Grayscale8 - }, - // Tiled - { - 0, // Invalid - fetchUntransformed64, // Mono - fetchUntransformed64, // MonoLsb - fetchUntransformed64, // Indexed8 - fetchUntransformed64, // RGB32 - fetchUntransformed64, // ARGB32 - fetchUntransformed64, // ARGB32_Premultiplied - fetchUntransformed64, // RGB16 - fetchUntransformed64, // ARGB8565_Premultiplied - fetchUntransformed64, // RGB666 - fetchUntransformed64, // ARGB6666_Premultiplied - fetchUntransformed64, // RGB555 - fetchUntransformed64, // ARGB8555_Premultiplied - fetchUntransformed64, // RGB888 - fetchUntransformed64, // RGB444 - fetchUntransformed64, // ARGB4444_Premultiplied - fetchUntransformed64, // RGBX8888 - fetchUntransformed64, // RGBA8888 - fetchUntransformed64, // RGBA8888_Premultiplied - fetchUntransformed64, // BGR30 - fetchUntransformed64, // A2BGR30_Premultiplied - fetchUntransformed64, // RGB30 - fetchUntransformed64, // A2RGB30_Premultiplied - fetchUntransformed64, // Alpha8 - fetchUntransformed64, // Grayscale8 - }, - // Transformed - { - 0, // Invalid - fetchTransformed64, // Mono - fetchTransformed64, // MonoLsb - fetchTransformed64, // Indexed8 - fetchTransformed64, // RGB32 - fetchTransformed64, // ARGB32 - fetchTransformed64, // ARGB32_Premultiplied - fetchTransformed64, // RGB16 - fetchTransformed64, // ARGB8565_Premultiplied - fetchTransformed64, // RGB666 - fetchTransformed64, // ARGB6666_Premultiplied - fetchTransformed64, // RGB555 - fetchTransformed64, // ARGB8555_Premultiplied - fetchTransformed64, // RGB888 - fetchTransformed64, // RGB444 - fetchTransformed64, // ARGB4444_Premultiplied - fetchTransformed64, // RGBX8888 - fetchTransformed64, // RGBA8888 - fetchTransformed64, // RGBA8888_Premultiplied - fetchTransformed64, // BGR30 - fetchTransformed64, // A2BGR30_Premultiplied - fetchTransformed64, // RGB30 - fetchTransformed64, // A2RGB30_Premultiplied - fetchTransformed64, // Alpah8 - fetchTransformed64, // Grayscale8 - }, - { - 0, // TransformedTiled - fetchTransformed64, // Mono - fetchTransformed64, // MonoLsb - fetchTransformed64, // Indexed8 - fetchTransformed64, // RGB32 - fetchTransformed64, // ARGB32 - fetchTransformed64, // ARGB32_Premultiplied - fetchTransformed64, // RGB16 - fetchTransformed64, // ARGB8565_Premultiplied - fetchTransformed64, // RGB666 - fetchTransformed64, // ARGB6666_Premultiplied - fetchTransformed64, // RGB555 - fetchTransformed64, // ARGB8555_Premultiplied - fetchTransformed64, // RGB888 - fetchTransformed64, // RGB444 - fetchTransformed64, // ARGB4444_Premultiplied - fetchTransformed64, // RGBX8888 - fetchTransformed64, // RGBA8888 - fetchTransformed64, // RGBA8888_Premultiplied - fetchTransformed64, // BGR30 - fetchTransformed64, // A2BGR30_Premultiplied - fetchTransformed64, // RGB30 - fetchTransformed64, // A2RGB30_Premultiplied - fetchTransformed64, // Alpha8 - fetchTransformed64, // Grayscale8 - }, - { - 0, // Bilinear - fetchTransformedBilinear64, // Mono - fetchTransformedBilinear64, // MonoLsb - fetchTransformedBilinear64, // Indexed8 - fetchTransformedBilinear64, // RGB32 - fetchTransformedBilinear64, // ARGB32 - fetchTransformedBilinear64, // ARGB32_Premultiplied - fetchTransformedBilinear64, // RGB16 - fetchTransformedBilinear64, // ARGB8565_Premultiplied - fetchTransformedBilinear64, // RGB666 - fetchTransformedBilinear64, // ARGB6666_Premultiplied - fetchTransformedBilinear64, // RGB555 - fetchTransformedBilinear64, // ARGB8555_Premultiplied - fetchTransformedBilinear64, // RGB888 - fetchTransformedBilinear64, // RGB444 - fetchTransformedBilinear64, // ARGB4444_Premultiplied - fetchTransformedBilinear64, // RGBX8888 - fetchTransformedBilinear64, // RGBA8888 - fetchTransformedBilinear64, // RGBA8888_Premultiplied - fetchTransformedBilinear64, // BGR30 - fetchTransformedBilinear64, // A2BGR30_Premultiplied - fetchTransformedBilinear64, // RGB30 - fetchTransformedBilinear64, // A2RGB30_Premultiplied - fetchTransformedBilinear64, // Alpha8 - fetchTransformedBilinear64, // Grayscale8 - }, - { - 0, // BilinearTiled - fetchTransformedBilinear64, // Mono - fetchTransformedBilinear64, // MonoLsb - fetchTransformedBilinear64, // Indexed8 - fetchTransformedBilinear64, // RGB32 - fetchTransformedBilinear64, // ARGB32 - fetchTransformedBilinear64, // ARGB32_Premultiplied - fetchTransformedBilinear64, // RGB16 - fetchTransformedBilinear64, // ARGB8565_Premultiplied - fetchTransformedBilinear64, // RGB666 - fetchTransformedBilinear64, // ARGB6666_Premultiplied - fetchTransformedBilinear64, // RGB555 - fetchTransformedBilinear64, // ARGB8555_Premultiplied - fetchTransformedBilinear64, // RGB888 - fetchTransformedBilinear64, // RGB444 - fetchTransformedBilinear64, // ARGB4444_Premultiplied - fetchTransformedBilinear64, // RGBX8888 - fetchTransformedBilinear64, // RGBA8888 - fetchTransformedBilinear64, // RGBA8888_Premultiplied - fetchTransformedBilinear64, // BGR30 - fetchTransformedBilinear64, // A2BGR30_Premultiplied - fetchTransformedBilinear64, // RGB30 - fetchTransformedBilinear64, // A2RGB30_Premultiplied - fetchTransformedBilinear64, // Alpha8 - fetchTransformedBilinear64, // Grayscale8 - }, +static const SourceFetchProc sourceFetchGeneric[NBlendTypes] = { + fetchUntransformed, // Untransformed + fetchUntransformed, // Tiled + fetchTransformed, // Transformed + fetchTransformed, // TransformedTiled + fetchTransformedBilinear, // Bilinear + fetchTransformedBilinear // BilinearTiled +}; + +static SourceFetchProc sourceFetchARGB32PM[NBlendTypes] = { + fetchUntransformedARGB32PM, // Untransformed + fetchUntransformedARGB32PM, // Tiled + fetchTransformedARGB32PM, // Transformed + fetchTransformedARGB32PM, // TransformedTiled + fetchTransformedBilinearARGB32PM, // Bilinear + fetchTransformedBilinearARGB32PM // BilinearTiled }; +static const SourceFetchProc64 sourceFetchGeneric64[NBlendTypes] = { + fetchUntransformed64, // Untransformed + fetchUntransformed64, // Tiled + fetchTransformed64, // Transformed + fetchTransformed64, // TransformedTiled + fetchTransformedBilinear64, // Bilinear + fetchTransformedBilinear64 // BilinearTiled +}; + +static inline SourceFetchProc getSourceFetch(TextureBlendType blendType, QImage::Format format) +{ + if (format == QImage::Format_RGB32 || format == QImage::Format_ARGB32_Premultiplied) + return sourceFetchARGB32PM[blendType]; + if (blendType == BlendUntransformed || blendType == BlendTiled) + return sourceFetchUntransformed[format]; + return sourceFetchGeneric[blendType]; +} + + #define FIXPT_BITS 8 #define FIXPT_SIZE (1<texture.hasAlpha; - op.srcFetch = sourceFetch[getBlendType(data)][data->texture.format]; - op.srcFetch64 = sourceFetch64[getBlendType(data)][data->texture.format]; + op.srcFetch = getSourceFetch(getBlendType(data), data->texture.format); + op.srcFetch64 = sourceFetchGeneric64[getBlendType(data)]; break; default: Q_UNREACHABLE(); @@ -5483,181 +5213,67 @@ static void blend_transformed_tiled_rgb565(int count, const QSpan *spans, void * /* Image formats here are target formats */ -static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats] = { - // Untransformed - { - 0, // Invalid - blend_untransformed_generic, // Mono - blend_untransformed_generic, // MonoLsb - blend_untransformed_generic, // Indexed8 - blend_untransformed_generic, // RGB32 - blend_untransformed_generic, // ARGB32 - blend_untransformed_argb, // ARGB32_Premultiplied - blend_untransformed_rgb565, - blend_untransformed_generic, - blend_untransformed_generic, - blend_untransformed_generic, - blend_untransformed_generic, - blend_untransformed_generic, - blend_untransformed_generic, - blend_untransformed_generic, - blend_untransformed_generic, - blend_untransformed_generic, - blend_untransformed_generic, - blend_untransformed_generic, - blend_untransformed_generic_rgb64, - blend_untransformed_generic_rgb64, - blend_untransformed_generic_rgb64, - blend_untransformed_generic_rgb64, - blend_untransformed_generic, - blend_untransformed_generic, - }, - // Tiled - { - 0, // Invalid - blend_tiled_generic, // Mono - blend_tiled_generic, // MonoLsb - blend_tiled_generic, // Indexed8 - blend_tiled_generic, // RGB32 - blend_tiled_generic, // ARGB32 - blend_tiled_argb, // ARGB32_Premultiplied - blend_tiled_rgb565, - blend_tiled_generic, - blend_tiled_generic, - blend_tiled_generic, - blend_tiled_generic, - blend_tiled_generic, - blend_tiled_generic, - blend_tiled_generic, - blend_tiled_generic, - blend_tiled_generic, - blend_tiled_generic, - blend_tiled_generic, - blend_tiled_generic_rgb64, - blend_tiled_generic_rgb64, - blend_tiled_generic_rgb64, - blend_tiled_generic_rgb64, - blend_tiled_generic, - blend_tiled_generic, - }, - // Transformed - { - 0, // Invalid - blend_src_generic, // Mono - blend_src_generic, // MonoLsb - blend_src_generic, // Indexed8 - blend_src_generic, // RGB32 - blend_src_generic, // ARGB32 - blend_transformed_argb, // ARGB32_Premultiplied - blend_transformed_rgb565, - blend_src_generic, // ARGB8565_Premultiplied - blend_src_generic, // RGB666 - blend_src_generic, // ARGB6666_Premultiplied - blend_src_generic, // RGB555 - blend_src_generic, // ARGB8555_Premultiplied - blend_src_generic, // RGB888 - blend_src_generic, // RGB444 - blend_src_generic, // ARGB4444_Premultiplied - blend_src_generic, // RGBX8888 - blend_src_generic, // RGBA8888 - blend_src_generic, // RGBA8888_Premultiplied - blend_src_generic_rgb64, - blend_src_generic_rgb64, - blend_src_generic_rgb64, - blend_src_generic_rgb64, - blend_src_generic, - blend_src_generic, - }, - // TransformedTiled - { - 0, - blend_src_generic, // Mono - blend_src_generic, // MonoLsb - blend_src_generic, // Indexed8 - blend_src_generic, // RGB32 - blend_src_generic, // ARGB32 - blend_transformed_tiled_argb, // ARGB32_Premultiplied - blend_transformed_tiled_rgb565, - blend_src_generic, // ARGB8565_Premultiplied - blend_src_generic, // RGB666 - blend_src_generic, // ARGB6666_Premultiplied - blend_src_generic, // RGB555 - blend_src_generic, // ARGB8555_Premultiplied - blend_src_generic, // RGB888 - blend_src_generic, // RGB444 - blend_src_generic, // ARGB4444_Premultiplied - blend_src_generic, // RGBX8888 - blend_src_generic, // RGBA8888 - blend_src_generic, // RGBA8888_Premultiplied - blend_src_generic_rgb64, - blend_src_generic_rgb64, - blend_src_generic_rgb64, - blend_src_generic_rgb64, - blend_src_generic, - blend_src_generic, - }, - // Bilinear - { - 0, - blend_src_generic, // Mono - blend_src_generic, // MonoLsb - blend_src_generic, // Indexed8 - blend_src_generic, // RGB32 - blend_src_generic, // ARGB32 - blend_src_generic, // ARGB32_Premultiplied - blend_transformed_bilinear_rgb565, - blend_src_generic, // ARGB8565_Premultiplied - blend_src_generic, // RGB666 - blend_src_generic, // ARGB6666_Premultiplied - blend_src_generic, // RGB555 - blend_src_generic, // ARGB8555_Premultiplied - blend_src_generic, // RGB888 - blend_src_generic, // RGB444 - blend_src_generic, // ARGB4444_Premultiplied - blend_src_generic, // RGBX8888 - blend_src_generic, // RGBA8888 - blend_src_generic, // RGBA8888_Premultiplied - blend_src_generic_rgb64, - blend_src_generic_rgb64, - blend_src_generic_rgb64, - blend_src_generic_rgb64, - blend_src_generic, - blend_src_generic, - }, - // BilinearTiled - { - 0, - blend_src_generic, // Mono - blend_src_generic, // MonoLsb - blend_src_generic, // Indexed8 - blend_src_generic, // RGB32 - blend_src_generic, // ARGB32 - blend_src_generic, // ARGB32_Premultiplied - blend_src_generic, // RGB16 - blend_src_generic, // ARGB8565_Premultiplied - blend_src_generic, // RGB666 - blend_src_generic, // ARGB6666_Premultiplied - blend_src_generic, // RGB555 - blend_src_generic, // ARGB8555_Premultiplied - blend_src_generic, // RGB888 - blend_src_generic, // RGB444 - blend_src_generic, // ARGB4444_Premultiplied - blend_src_generic, // RGBX8888 - blend_src_generic, // RGBA8888 - blend_src_generic, // RGBA8888_Premultiplied - blend_src_generic_rgb64, // BGR30 - blend_src_generic_rgb64, // A2BGR30_Premultiplied - blend_src_generic_rgb64, // RGB30 - blend_src_generic_rgb64, // A2RGB30_Premultiplied - blend_src_generic, // Alpha8 - blend_src_generic, // Grayscale8 - } +static const ProcessSpans processTextureSpansARGB32PM[NBlendTypes] = { + blend_untransformed_argb, // Untransformed + blend_tiled_argb, // Tiled + blend_transformed_argb, // Transformed + blend_transformed_tiled_argb, // TransformedTiled + blend_src_generic, // TransformedBilinear + blend_src_generic // TransformedBilinearTiled +}; + +static const ProcessSpans processTextureSpansRGB16[NBlendTypes] = { + blend_untransformed_rgb565, // Untransformed + blend_tiled_rgb565, // Tiled + blend_transformed_rgb565, // Transformed + blend_transformed_tiled_rgb565, // TransformedTiled + blend_transformed_bilinear_rgb565, // TransformedBilinear + blend_src_generic // TransformedBilinearTiled +}; + +static const ProcessSpans processTextureSpansGeneric[NBlendTypes] = { + blend_untransformed_generic, // Untransformed + blend_tiled_generic, // Tiled + blend_src_generic, // Transformed + blend_src_generic, // TransformedTiled + blend_src_generic, // TransformedBilinear + blend_src_generic // TransformedBilinearTiled +}; + +static const ProcessSpans processTextureSpansGeneric64[NBlendTypes] = { + blend_untransformed_generic_rgb64, // Untransformed + blend_tiled_generic_rgb64, // Tiled + blend_src_generic_rgb64, // Transformed + blend_src_generic_rgb64, // TransformedTiled + blend_src_generic_rgb64, // TransformedBilinear + blend_src_generic_rgb64 // TransformedBilinearTiled }; void qBlendTexture(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); - ProcessSpans proc = processTextureSpans[getBlendType(data)][data->rasterBuffer->format]; + TextureBlendType blendType = getBlendType(data); + ProcessSpans proc; + switch (data->rasterBuffer->format) { + case QImage::Format_ARGB32_Premultiplied: + proc = processTextureSpansARGB32PM[blendType]; + break; + case QImage::Format_RGB16: + proc = processTextureSpansRGB16[blendType]; + break; + case QImage::Format_BGR30: + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_RGB30: + case QImage::Format_A2RGB30_Premultiplied: + proc = processTextureSpansGeneric64[blendType]; + break; + case QImage::Format_Invalid: + Q_UNREACHABLE(); + return; + default: + proc = processTextureSpansGeneric[blendType]; + break; + } proc(count, spans, userData); } @@ -6572,8 +6188,7 @@ static void qInitDrawhelperFunctions() qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; qStorePixels[QPixelLayout::BPP24] = storePixelsBPP24_ssse3; - sourceFetch[BlendUntransformed][QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3; - sourceFetch[BlendTiled][QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3; + sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3; } #endif // SSSE3 @@ -6658,8 +6273,7 @@ static void qInitDrawhelperFunctions() qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon; - sourceFetch[BlendUntransformed][QImage::Format_RGB888] = qt_fetchUntransformed_888_neon; - sourceFetch[BlendTiled][QImage::Format_RGB888] = qt_fetchUntransformed_888_neon; + sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_neon; #if defined(ENABLE_PIXMAN_DRAWHELPERS) // The RGB16 helpers are using Arm32 assemblythat has not been ported to AArch64 @@ -6720,14 +6334,9 @@ static void qInitDrawhelperFunctions() destStoreProc[QImage::Format_ARGB32] = qt_destStoreARGB32_mips_dsp; - sourceFetch[BlendUntransformed][QImage::Format_RGB888] = qt_fetchUntransformed_888_mips_dsp; - sourceFetch[BlendTiled][QImage::Format_RGB888] = qt_fetchUntransformed_888_mips_dsp; - - sourceFetch[BlendUntransformed][QImage::Format_RGB444] = qt_fetchUntransformed_444_mips_dsp; - sourceFetch[BlendTiled][QImage::Format_RGB444] = qt_fetchUntransformed_444_mips_dsp; - - sourceFetch[BlendUntransformed][QImage::Format_ARGB8565_Premultiplied] = qt_fetchUntransformed_argb8565_premultiplied_mips_dsp; - sourceFetch[BlendTiled][QImage::Format_ARGB8565_Premultiplied] = qt_fetchUntransformed_argb8565_premultiplied_mips_dsp; + sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_mips_dsp; + sourceFetchUntransformed[QImage::Format_RGB444] = qt_fetchUntransformed_444_mips_dsp; + sourceFetchUntransformed[QImage::Format_ARGB8565_Premultiplied] = qt_fetchUntransformed_argb8565_premultiplied_mips_dsp; #if defined(QT_COMPILER_SUPPORTS_MIPS_DSPR2) qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_mips_dspr2; -- cgit v1.2.3 From b69ac5a0afdea04e75e598a9e0ae1f8c60678b9b Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Tue, 20 Sep 2016 12:58:04 +0200 Subject: Doc: corrected mistaken refernce to macro \macos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I734943820400384a2f9ac7e148dc42d3428b0732 Reviewed-by: Topi Reiniö Reviewed-by: Jake Petroules --- src/corelib/global/qglobal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index a9a583d808..743d9d14a5 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1253,7 +1253,7 @@ bool qSharedBuild() Q_DECL_NOTHROW \macro Q_OS_DARWIN \relates - Defined on Darwin-based operating systems such as \macOS, iOS, watchOS, and tvOS. + Defined on Darwin-based operating systems such as \macos, iOS, watchOS, and tvOS. */ /*! -- cgit v1.2.3 From 31c251765db45a068f1268027e5dd600151af1e5 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Sun, 20 Mar 2016 15:35:23 +0100 Subject: Save memcpy when converting to 32bit formats If the destination format is 32bit, we can convert directly in the destination instead of in a buffer. Change-Id: I2b4407da77b863deec7869c341e1a8d464b46600 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/gui/image/qimage_conversions.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 442492d198..9bd098b7b1 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -134,7 +134,8 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio Q_ASSERT(dest->format > QImage::Format_Indexed8); Q_ASSERT(src->format > QImage::Format_Indexed8); const int buffer_size = 2048; - uint buffer[buffer_size]; + uint buf[buffer_size]; + uint *buffer = buf; const QPixelLayout *srcLayout = &qPixelLayouts[src->format]; const QPixelLayout *destLayout = &qPixelLayouts[dest->format]; const uchar *srcData = src->data; @@ -169,11 +170,16 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio int x = 0; while (x < src->width) { dither.x = x; - int l = qMin(src->width - x, buffer_size); + int l = src->width - x; + if (destLayout->bpp == QPixelLayout::BPP32) + buffer = reinterpret_cast(destData) + x; + else + l = qMin(l, buffer_size); const uint *ptr = fetch(buffer, srcData, x, l); ptr = convertToARGB32PM(buffer, ptr, l, 0, ditherPtr); ptr = convertFromARGB32PM(buffer, ptr, l, 0, ditherPtr); - store(destData, ptr, x, l); + if (ptr != reinterpret_cast(destData)) + store(destData, ptr, x, l); x += l; } srcData += src->bytes_per_line; -- cgit v1.2.3