diff options
author | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-03-16 10:31:07 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-03-16 10:31:07 +0100 |
commit | 198606f6dbca95ba3a170fff387327d8271018cd (patch) | |
tree | 79e8c632f5277fc7f0ae30ae7fb1e1c41745c815 | |
parent | 77c0c1ca6505eb66bd75b3766f9a498574822bd1 (diff) | |
parent | 0d5ffd67a4748bcbf19dc3a4b9a36ae6314e58a6 (diff) |
Merge remote-tracking branch 'origin/5.5' into dev
Conflicts:
src/plugins/platforms/xcb/qxcbnativeinterface.cpp
src/plugins/platforms/xcb/qxcbnativeinterface.h
Change-Id: I31b38ba439b9341d51a01c0fd54bea33f7410076
259 files changed, 4364 insertions, 2608 deletions
diff --git a/examples/network/doc/images/googlesuggest-example.png b/examples/network/doc/images/googlesuggest-example.png Binary files differindex 477d444cbd..c704f5b2b4 100644 --- a/examples/network/doc/images/googlesuggest-example.png +++ b/examples/network/doc/images/googlesuggest-example.png diff --git a/examples/network/doc/src/googlesuggest.qdoc b/examples/network/doc/src/googlesuggest.qdoc index 912947dfdf..168515446f 100644 --- a/examples/network/doc/src/googlesuggest.qdoc +++ b/examples/network/doc/src/googlesuggest.qdoc @@ -68,12 +68,8 @@ in the explicit \c editor member variable. We then create a QTreeWidget as a toplevel widget and configure the various - properties to give it the look of a popup widget. - - The popup will be populated by the results returned from Google. We set - the number of columns to be two, since we want to display both the - suggested search term and the number of hits it will trigger in the search - engine. + properties to give it the look of a popup widget. The widget is populated + with the results by Google Suggest API request. Furthermore, we install the GSuggestCompletion instance as an event filter on the QTreeWidget, and connect the \c itemClicked() signal with the \c @@ -110,8 +106,8 @@ \snippet googlesuggest/googlesuggest.cpp 4 The \c showCompletion() function populates the QTreeWidget with the results - returned from the query. It takes two QStringLists, one with the suggested - search terms and the other with the corresponding number of hits. + returned from the query. It takes a QStringList of the suggested search + terms. \snippet googlesuggest/googlesuggest.cpp 5 diff --git a/examples/network/googlesuggest/googlesuggest.cpp b/examples/network/googlesuggest/googlesuggest.cpp index ce727e7675..576629d46b 100644 --- a/examples/network/googlesuggest/googlesuggest.cpp +++ b/examples/network/googlesuggest/googlesuggest.cpp @@ -38,7 +38,6 @@ ** ****************************************************************************/ - //! [1] #include "googlesuggest.h" @@ -54,7 +53,7 @@ GSuggestCompletion::GSuggestCompletion(QLineEdit *parent): QObject(parent), edit popup->setFocusProxy(parent); popup->setMouseTracking(true); - popup->setColumnCount(2); + popup->setColumnCount(1); popup->setUniformRowHeights(true); popup->setRootIsDecorated(false); popup->setEditTriggers(QTreeWidget::NoEditTriggers); @@ -137,10 +136,10 @@ bool GSuggestCompletion::eventFilter(QObject *obj, QEvent *ev) //! [4] //! [5] -void GSuggestCompletion::showCompletion(const QStringList &choices, const QStringList &hits) +void GSuggestCompletion::showCompletion(const QStringList &choices) { - if (choices.isEmpty() || choices.count() != hits.count()) + if (choices.isEmpty()) return; const QPalette &pal = editor->palette(); @@ -152,19 +151,12 @@ void GSuggestCompletion::showCompletion(const QStringList &choices, const QStrin QTreeWidgetItem * item; item = new QTreeWidgetItem(popup); item->setText(0, choices[i]); - item->setText(1, hits[i]); - item->setTextAlignment(1, Qt::AlignRight); - item->setTextColor(1, color); + item->setTextColor(0, color); } popup->setCurrentItem(popup->topLevelItem(0)); popup->resizeColumnToContents(0); - popup->resizeColumnToContents(1); - popup->adjustSize(); popup->setUpdatesEnabled(true); - int h = popup->sizeHintForRow(0) * qMin(7, choices.count()) + 3; - popup->resize(popup->width(), h); - popup->move(editor->mapToGlobal(QPoint(0, editor->height()))); popup->setFocus(); popup->show(); @@ -207,7 +199,6 @@ void GSuggestCompletion::handleNetworkData(QNetworkReply *networkReply) QUrl url = networkReply->url(); if (!networkReply->error()) { QStringList choices; - QStringList hits; QByteArray response(networkReply->readAll()); QXmlStreamReader xml(response); @@ -218,17 +209,11 @@ void GSuggestCompletion::handleNetworkData(QNetworkReply *networkReply) QStringRef str = xml.attributes().value("data"); choices << str.toString(); } - if (xml.tokenType() == QXmlStreamReader::StartElement) - if (xml.name() == "num_queries") { - QStringRef str = xml.attributes().value("int"); - hits << str.toString(); - } } - showCompletion(choices, hits); + showCompletion(choices); } networkReply->deleteLater(); } //! [9] - diff --git a/examples/network/googlesuggest/googlesuggest.h b/examples/network/googlesuggest/googlesuggest.h index dfa04cd009..e53fe996d4 100644 --- a/examples/network/googlesuggest/googlesuggest.h +++ b/examples/network/googlesuggest/googlesuggest.h @@ -61,7 +61,7 @@ public: GSuggestCompletion(QLineEdit *parent = 0); ~GSuggestCompletion(); bool eventFilter(QObject *obj, QEvent *ev) Q_DECL_OVERRIDE; - void showCompletion(const QStringList &choices, const QStringList &hits); + void showCompletion(const QStringList &choices); public slots: diff --git a/mkspecs/common/qcc-base-qnx-armle-v7.conf b/mkspecs/common/qcc-base-qnx-armle-v7.conf index 331a65b2bf..12d393f070 100644 --- a/mkspecs/common/qcc-base-qnx-armle-v7.conf +++ b/mkspecs/common/qcc-base-qnx-armle-v7.conf @@ -10,6 +10,7 @@ include(unix.conf) QMAKE_CC = qcc -Vgcc_ntoarmv7le QMAKE_CXX = qcc -Vgcc_ntoarmv7le QNX_CPUDIR = armle-v7 +QMAKE_CFLAGS += -mfpu=neon include(qcc-base-qnx.conf) diff --git a/mkspecs/common/qcc-base.conf b/mkspecs/common/qcc-base.conf index f529d7fc7b..09fdabce43 100644 --- a/mkspecs/common/qcc-base.conf +++ b/mkspecs/common/qcc-base.conf @@ -33,7 +33,6 @@ QMAKE_CFLAGS_SSE4_1 += -msse4.1 QMAKE_CFLAGS_SSE4_2 += -msse4.2 QMAKE_CFLAGS_AVX += -mavx QMAKE_CFLAGS_AVX2 += -mavx2 -QMAKE_CFLAGS_NEON += -mfpu=neon QMAKE_CXXFLAGS += $$QMAKE_CFLAGS -lang-c++ QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index ff1f5f8940..89870f4f51 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -80,7 +80,7 @@ defineTest(qtAddModule) { unset(LINKAGE) mac:contains(MODULE_CONFIG, lib_bundle) { FRAMEWORK_INCLUDE = $${MODULE_LIBS}/$${MODULE_NAME}.framework/Headers - !qt_no_framework_direct_includes:exists($$FRAMEWORK_INCLUDE) { + !qt_no_framework_direct_includes { INCLUDEPATH *= $$FRAMEWORK_INCLUDE } contains(MODULE_CONFIG, internal_module): \ diff --git a/mkspecs/features/static_runtime.prf b/mkspecs/features/static_runtime.prf new file mode 100644 index 0000000000..3275e6e2e2 --- /dev/null +++ b/mkspecs/features/static_runtime.prf @@ -0,0 +1,7 @@ +msvc { + # -MD becomes -MT, -MDd becomes -MTd + QMAKE_CFLAGS ~= s,^-MD(d?)$, -MT\1,g + QMAKE_CXXFLAGS ~= s,^-MD(d?)$, -MT\1,g +} else: mingw { + QMAKE_LFLAGS += -static +} diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf index c77f3b70ab..a6ef930128 100644 --- a/mkspecs/features/testcase.prf +++ b/mkspecs/features/testcase.prf @@ -52,25 +52,18 @@ insignificant_test:check.commands = -$${check.commands} QMAKE_EXTRA_TARGETS *= check -!debug_and_release|build_pass { +isEmpty(BUILDS)|build_pass { check.depends = first } else { + # For exclusive builds, only run the test once. check.CONFIG = recursive - # In debug and release mode, only run the test once. - # Run debug if that is the preferred config, release otherwise. - debug_and_release { - check.target = dummy_check - check.recurse_target = check - CONFIG(debug, debug|release) { - real_check.depends = debug-check - real_check.target = check - QMAKE_EXTRA_TARGETS += real_check - } else { - real_check.depends = release-check - real_check.target = check - QMAKE_EXTRA_TARGETS += real_check - } - } + check.target = check_all + check.recurse_target = check + check.commands = + + check_first.depends = $$eval($$first(BUILDS).target)-check + check_first.target = check + QMAKE_EXTRA_TARGETS += check_first } !no_testcase_installs:!contains(INSTALLS, target) { diff --git a/mkspecs/features/unix/separate_debug_info.prf b/mkspecs/features/unix/separate_debug_info.prf index 394d5f42bc..7d9022f8d7 100644 --- a/mkspecs/features/unix/separate_debug_info.prf +++ b/mkspecs/features/unix/separate_debug_info.prf @@ -9,19 +9,21 @@ have_target:!static:!isEmpty(QMAKE_OBJCOPY) { debug_info_keep = --only-keep-debug debug_info_strip = --strip-debug } - QMAKE_SEPARATE_DEBUG_INFO = test -z \"$(DESTDIR)\" || cd \"$(DESTDIR)\" ; targ=`basename $(TARGET)`; $$QMAKE_OBJCOPY $$debug_info_keep \"\$\$targ\" \"\$\$targ.$$debug_info_suffix\" && $$QMAKE_OBJCOPY $$debug_info_strip \"\$\$targ\" && $$QMAKE_OBJCOPY --add-gnu-debuglink=\"\$\$targ.$$debug_info_suffix\" \"\$\$targ\" && chmod -x \"\$\$targ.$$debug_info_suffix\" - QMAKE_INSTALL_SEPARATE_DEBUG_INFO = test -z \"$(DESTDIR)\" || cd \"$(DESTDIR)\" ; $(INSTALL_FILE) `basename $(TARGET)`.$$debug_info_suffix $(INSTALL_ROOT)/\$\$target_path/ + load(resolve_target) + QMAKE_TARGET_DEBUG_INFO = $${QMAKE_RESOLVED_TARGET}.$$debug_info_suffix + + shell_target = $$shell_quote($$relative_path($$QMAKE_RESOLVED_TARGET, $$OUT_PWD)) + shell_target_debug_info = $$shell_quote($$relative_path($$QMAKE_TARGET_DEBUG_INFO, $$OUT_PWD)) + copy_debug_info = $$QMAKE_OBJCOPY $$debug_info_keep $$shell_target $$shell_target_debug_info + strip_debug_info = $$QMAKE_OBJCOPY $$debug_info_strip $$shell_target + link_debug_info = $$QMAKE_OBJCOPY --add-gnu-debuglink=$$shell_target_debug_info $$shell_target + chmod_debug_info = chmod -x $$shell_target_debug_info !isEmpty(QMAKE_POST_LINK):QMAKE_POST_LINK = $$escape_expand(\\n\\t)$$QMAKE_POST_LINK - QMAKE_POST_LINK = $$QMAKE_SEPARATE_DEBUG_INFO $$QMAKE_POST_LINK + QMAKE_POST_LINK = $$copy_debug_info && $$strip_debug_info && $$link_debug_info && $$chmod_debug_info $$QMAKE_POST_LINK silent:QMAKE_POST_LINK = @echo creating $@.$$debug_info_suffix && $$QMAKE_POST_LINK - isEmpty(DESTDIR) { - target.targets += "`basename $(TARGET)`.$$debug_info_suffix" - QMAKE_DISTCLEAN += "`basename $(TARGET)`.$$debug_info_suffix" - } else { - target.targets += "$(DESTDIR)/`basename $(TARGET)`.$$debug_info_suffix" - QMAKE_DISTCLEAN += "$(DESTDIR)/`basename $(TARGET)`.$$debug_info_suffix" - } + target.targets += $$QMAKE_TARGET_DEBUG_INFO + QMAKE_DISTCLEAN += $$QMAKE_TARGET_DEBUG_INFO } diff --git a/mkspecs/features/winrt/package_manifest.prf b/mkspecs/features/winrt/package_manifest.prf index 6726611f74..7e5effa438 100644 --- a/mkspecs/features/winrt/package_manifest.prf +++ b/mkspecs/features/winrt/package_manifest.prf @@ -71,7 +71,9 @@ exists($$UUID_CACHE) { include($$UUID_CACHE) } else { - WINRT_UUID = "WINRT_MANIFEST.identity = $$system(uuidgen)" + WINRT_UUID = $$system(uuidgen) + isEmpty(WINRT_UUID): error("Unable to generate a UUID. Make sure uuidgen is in your PATH.") + WINRT_UUID = "WINRT_MANIFEST.identity = $$WINRT_UUID" write_file($$UUID_CACHE, WINRT_UUID)|error("Unable to write the UUID cache; aborting.") eval($$WINRT_UUID) } diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf index f9a8921a09..c9d3a5d85b 100644 --- a/mkspecs/macx-ios-clang/features/default_post.prf +++ b/mkspecs/macx-ios-clang/features/default_post.prf @@ -41,7 +41,6 @@ equals(TEMPLATE, app) { RESOURCES = INSTALLS = QMAKE_EXTRA_COMPILERS = - QMAKE_EXTRA_TARGETS = !build_pass { CONFIG += debug_and_release @@ -97,7 +96,24 @@ equals(TEMPLATE, app) { target = $${sdk}-$${cfg}$${action_target_suffix} - $${target}.commands = "@bash -o pipefail -c 'xcodebuild $$action -scheme $(TARGET) -sdk $$sdk -configuration $$title($$cfg) | grep -v setenv'" + xcodebuild = "xcodebuild $$action -scheme $(TARGET) -sdk $$sdk -configuration $$title($$cfg)" + + equals(action, test):equals(sdk, iphoneos) { + AVAILABLE_DEVICE_IDS = "$(shell system_profiler SPUSBDataType | sed -n -E -e '/(iPhone|iPad|iPod)/,/Serial/s/ *Serial Number: *(.+)/\1/p')" + CUSTOM_DEVICE_IDS = "$(filter $(EXPORT_AVAILABLE_DEVICE_IDS), $(IOS_TEST_DEVICE_IDS))" + TEST_DEVICE_IDS = "$(strip $(if $(EXPORT_CUSTOM_DEVICE_IDS), $(EXPORT_CUSTOM_DEVICE_IDS), $(EXPORT_AVAILABLE_DEVICE_IDS)))" + + QMAKE_EXTRA_VARIABLES += AVAILABLE_DEVICE_IDS CUSTOM_DEVICE_IDS TEST_DEVICE_IDS + + xcodebuild = "@$(if $(EXPORT_TEST_DEVICE_IDS),"\ + "echo Running tests on $(words $(EXPORT_TEST_DEVICE_IDS)) device\\(s\\): && ("\ + "$(foreach deviceid, $(EXPORT_TEST_DEVICE_IDS),"\ + "(echo Testing on device ID '$(deviceid)' ... && $${xcodebuild} -destination 'platform=iOS,id=$(deviceid)' && echo) &&"\ + ") echo Tests completed successfully on all devices"\ + "), $(error No iOS devices connected, please connect at least one device that can be used for testing.))" + } + + $${target}.commands = $$xcodebuild QMAKE_EXTRA_TARGETS += $$target $${action_target}.depends += $$target diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index e2b5f5f90b..ec18d1f9b3 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -558,6 +558,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("name", "Qt Qmake") << ";\n" << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n" << "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n" + << "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n" << "\t\t};\n"; } @@ -795,6 +796,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("name", "Qt Preprocessors") << ";\n" << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n" << "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n" + << "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n" << "\t\t};\n"; } @@ -1070,6 +1072,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("name", "Qt Postlink") << ";\n" << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n" << "\t\t\t" << writeSettings("shellScript", project->values("QMAKE_POST_LINK")) << ";\n" + << "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n" << "\t\t};\n"; } @@ -1088,6 +1091,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n" << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n" << "\t\t\t" << writeSettings("shellScript", fixForOutput("cp -r $BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME " + IoUtils::shellQuoteUnix(destDir))) << ";\n" + << "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n" << "\t\t};\n"; } bool copyBundleResources = project->isActiveConfig("app_bundle") && project->first("TEMPLATE") == "app"; diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index c719aa4cbf..740c8c4d13 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -388,6 +388,7 @@ void NmakeMakefileGenerator::init() ProString version = project->first("TARGET_VERSION_EXT"); if(project->isActiveConfig("shared")) { project->values("QMAKE_CLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".exp"); + project->values("QMAKE_DISTCLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".lib"); } if (project->isActiveConfig("debug_info")) { QString pdbfile = project->first("DESTDIR") + project->first("TARGET") + version + ".pdb"; diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c index 1b3e162a7e..a8205065c5 100644 --- a/src/3rdparty/forkfd/forkfd.c +++ b/src/3rdparty/forkfd/forkfd.c @@ -38,7 +38,7 @@ #ifndef _GNU_SOURCE # define _GNU_SOURCE # define _POSIX_C_SOURCE 200809L -# define _XOPEN_SOURCE 500 +# define _XOPEN_SOURCE 700 #endif #include "forkfd.h" @@ -436,6 +436,7 @@ static int create_pipe(int filedes[], int flags) return ret; } +#ifndef FORKFD_NO_FORKFD /** * @brief forkfd returns a file descriptor representing a child process * @return a file descriptor, or -1 in case of failure @@ -590,8 +591,9 @@ err_free: freeInfo(header, info); return -1; } +#endif // FORKFD_NO_FORKFD -#ifdef _POSIX_SPAWN +#if defined(_POSIX_SPAWN) && !defined(FORKFD_NO_SPAWNFD) int spawnfd(int flags, pid_t *ppid, const char *path, const posix_spawn_file_actions_t *file_actions, posix_spawnattr_t *attrp, char *const argv[], char *const envp[]) { @@ -652,4 +654,4 @@ err_free: out: return -1; } -#endif // _POSIX_SPAWN +#endif // _POSIX_SPAWN && !FORKFD_NO_SPAWNFD diff --git a/src/3rdparty/freebsd/0001-Patch-the-FreeBSD-strto-u-ll-functions-to-work-insid.patch b/src/3rdparty/freebsd/0001-Patch-the-FreeBSD-strto-u-ll-functions-to-work-insid.patch index ac7580d5c4..b21d483a9c 100644 --- a/src/3rdparty/freebsd/0001-Patch-the-FreeBSD-strto-u-ll-functions-to-work-insid.patch +++ b/src/3rdparty/freebsd/0001-Patch-the-FreeBSD-strto-u-ll-functions-to-work-insid.patch @@ -9,15 +9,15 @@ Changes: - rename from strtoxx_l to qt_strtoxx (merging the two functions) - remove __restrict - remove the locale_t parameter and use ascii_isspace instead of isspace_l + - fix compilation with -Wcast-qual (requires C++) -Change-Id: I1e522e12da90eb35eefcf4025102dc11b22c60a5 --- - src/3rdparty/freebsd/strtoll.c | 27 +++++---------------------- - src/3rdparty/freebsd/strtoull.c | 27 +++++---------------------- - 2 files changed, 10 insertions(+), 44 deletions(-) + src/3rdparty/freebsd/strtoll.c | 27 ++++----------------------- + src/3rdparty/freebsd/strtoull.c | 27 ++++----------------------- + 2 files changed, 8 insertions(+), 46 deletions(-) diff --git a/src/3rdparty/freebsd/strtoll.c b/src/3rdparty/freebsd/strtoll.c -index 16a8196..0ded267 100644 +index 16a8196..7b4505e 100644 --- a/src/3rdparty/freebsd/strtoll.c +++ b/src/3rdparty/freebsd/strtoll.c @@ -32,18 +32,6 @@ @@ -39,7 +39,7 @@ index 16a8196..0ded267 100644 /* * Convert a string to a long long integer. * -@@ -51,15 +39,15 @@ __FBSDID("$FreeBSD$"); +@@ -51,15 +39,13 @@ __FBSDID("$FreeBSD$"); * alphabets and digits are each contiguous. */ long long @@ -72,7 +72,8 @@ index 16a8196..0ded267 100644 - acc = -acc; + acc = (unsigned long long) -(long long)acc; if (endptr != NULL) - *endptr = (char *)(any ? s - 1 : nptr); +- *endptr = (char *)(any ? s - 1 : nptr); ++ *endptr = const_cast<char *>(any ? s - 1 : nptr); return (acc); } -long long @@ -81,7 +82,7 @@ index 16a8196..0ded267 100644 - return strtoll_l(nptr, endptr, base, __get_locale()); -} diff --git a/src/3rdparty/freebsd/strtoull.c b/src/3rdparty/freebsd/strtoull.c -index dc40e0e..cb04adb 100644 +index dc40e0e..1eb9257 100644 --- a/src/3rdparty/freebsd/strtoull.c +++ b/src/3rdparty/freebsd/strtoull.c @@ -32,18 +32,6 @@ @@ -103,7 +104,7 @@ index dc40e0e..cb04adb 100644 /* * Convert a string to an unsigned long long integer. * -@@ -51,15 +39,15 @@ __FBSDID("$FreeBSD$"); +@@ -51,15 +39,13 @@ __FBSDID("$FreeBSD$"); * alphabets and digits are each contiguous. */ unsigned long long @@ -136,7 +137,8 @@ index dc40e0e..cb04adb 100644 - acc = -acc; + acc = (unsigned long long) -(long long)acc; if (endptr != NULL) - *endptr = (char *)(any ? s - 1 : nptr); +- *endptr = (char *)(any ? s - 1 : nptr); ++ *endptr = const_cast<char *>(any ? s - 1 : nptr); return (acc); } -unsigned long long @@ -145,5 +147,5 @@ index dc40e0e..cb04adb 100644 - return strtoull_l(nptr, endptr, base, __get_locale()); -} -- -1.8.4.5 +2.1.4 diff --git a/src/3rdparty/freebsd/strtoll.c b/src/3rdparty/freebsd/strtoll.c index 6f06e03dc8..7b4505eddc 100644 --- a/src/3rdparty/freebsd/strtoll.c +++ b/src/3rdparty/freebsd/strtoll.c @@ -129,6 +129,6 @@ noconv: } else if (neg) acc = (unsigned long long) -(long long)acc; if (endptr != NULL) - *endptr = (char *)(any ? s - 1 : nptr); + *endptr = const_cast<char *>(any ? s - 1 : nptr); return (acc); } diff --git a/src/3rdparty/freebsd/strtoull.c b/src/3rdparty/freebsd/strtoull.c index 7cb97f02f4..1eb92578d4 100644 --- a/src/3rdparty/freebsd/strtoull.c +++ b/src/3rdparty/freebsd/strtoull.c @@ -107,6 +107,6 @@ noconv: } else if (neg) acc = (unsigned long long) -(long long)acc; if (endptr != NULL) - *endptr = (char *)(any ? s - 1 : nptr); + *endptr = const_cast<char *>(any ? s - 1 : nptr); return (acc); } diff --git a/src/3rdparty/freetype.pri b/src/3rdparty/freetype.pri new file mode 100644 index 0000000000..33981c6e3c --- /dev/null +++ b/src/3rdparty/freetype.pri @@ -0,0 +1,67 @@ +QT_FREETYPE_DIR = $$PWD/freetype + +SOURCES += \ + $$QT_FREETYPE_DIR/src/autofit/afangles.c \ + $$QT_FREETYPE_DIR/src/autofit/afdummy.c \ + $$QT_FREETYPE_DIR/src/autofit/afglobal.c \ + $$QT_FREETYPE_DIR/src/autofit/afhints.c \ + $$QT_FREETYPE_DIR/src/autofit/aflatin.c \ + $$QT_FREETYPE_DIR/src/autofit/afloader.c \ + $$QT_FREETYPE_DIR/src/autofit/afmodule.c \ + $$QT_FREETYPE_DIR/src/autofit/autofit.c \ + $$QT_FREETYPE_DIR/src/base/ftbase.c \ + $$QT_FREETYPE_DIR/src/base/ftbitmap.c \ + $$QT_FREETYPE_DIR/src/base/ftbbox.c \ + $$QT_FREETYPE_DIR/src/base/ftdebug.c \ + $$QT_FREETYPE_DIR/src/base/ftglyph.c \ + $$QT_FREETYPE_DIR/src/base/ftinit.c \ + $$QT_FREETYPE_DIR/src/base/ftlcdfil.c \ + $$QT_FREETYPE_DIR/src/base/ftmm.c \ + $$QT_FREETYPE_DIR/src/base/ftsynth.c \ + $$QT_FREETYPE_DIR/src/base/fttype1.c \ + $$QT_FREETYPE_DIR/src/bdf/bdf.c \ + $$QT_FREETYPE_DIR/src/cache/ftcache.c \ + $$QT_FREETYPE_DIR/src/cff/cff.c \ + $$QT_FREETYPE_DIR/src/cid/type1cid.c \ + $$QT_FREETYPE_DIR/src/gzip/ftgzip.c \ + $$QT_FREETYPE_DIR/src/lzw/ftlzw.c \ + $$QT_FREETYPE_DIR/src/otvalid/otvalid.c \ + $$QT_FREETYPE_DIR/src/otvalid/otvbase.c \ + $$QT_FREETYPE_DIR/src/otvalid/otvcommn.c \ + $$QT_FREETYPE_DIR/src/otvalid/otvgdef.c \ + $$QT_FREETYPE_DIR/src/otvalid/otvgpos.c \ + $$QT_FREETYPE_DIR/src/otvalid/otvgsub.c \ + $$QT_FREETYPE_DIR/src/otvalid/otvjstf.c \ + $$QT_FREETYPE_DIR/src/otvalid/otvmod.c \ + $$QT_FREETYPE_DIR/src/pcf/pcf.c \ + $$QT_FREETYPE_DIR/src/pfr/pfr.c \ + $$QT_FREETYPE_DIR/src/psaux/psaux.c \ + $$QT_FREETYPE_DIR/src/pshinter/pshinter.c \ + $$QT_FREETYPE_DIR/src/psnames/psmodule.c \ + $$QT_FREETYPE_DIR/src/raster/raster.c \ + $$QT_FREETYPE_DIR/src/sfnt/sfnt.c \ + $$QT_FREETYPE_DIR/src/smooth/smooth.c \ + $$QT_FREETYPE_DIR/src/truetype/truetype.c \ + $$QT_FREETYPE_DIR/src/type1/type1.c \ + $$QT_FREETYPE_DIR/src/type42/type42.c \ + $$QT_FREETYPE_DIR/src/winfonts/winfnt.c + +win32 { + SOURCES += $$QT_FREETYPE_DIR/src/base/ftsystem.c +} else { + SOURCES += $$QT_FREETYPE_DIR/builds/unix/ftsystem.c + INCLUDEPATH += $$QT_FREETYPE_DIR/builds/unix +} + +INCLUDEPATH += $$QT_FREETYPE_DIR/src $$QT_FREETYPE_DIR/include + +DEFINES += FT2_BUILD_LIBRARY +contains(QT_CONFIG, system-zlib) { + DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB + include($$PWD/zlib_dependency.pri) +} + +# disable warnings about "unsafe" methods in C code +msvc:QMAKE_CFLAGS_WARN_ON += -wd"4996" + +TR_EXCLUDE += $$QT_FREETYPE_DIR/* diff --git a/src/3rdparty/harfbuzz-ng/NEWS b/src/3rdparty/harfbuzz-ng/NEWS index 3a33bdf5cb..dbbfbba195 100644 --- a/src/3rdparty/harfbuzz-ng/NEWS +++ b/src/3rdparty/harfbuzz-ng/NEWS @@ -1,3 +1,13 @@ +Overview of changes leading to 0.9.39 +Wednesday, March 4, 2015 +===================================== + +- Critical hb-coretext fixes. +- Optimizations and refactoring; no functional change + expected. +- Misc build fixes. + + Overview of changes leading to 0.9.38 Friday, January 23, 2015 ===================================== diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc index 0500aa23ce..942177cbd0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc @@ -454,7 +454,7 @@ hb_buffer_t::reverse_range (unsigned int start, info[j] = t; } - if (pos) { + if (have_positions) { for (i = start, j = end - 1; i < j; i++, j--) { hb_glyph_position_t t; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh index 7500c32f15..178bc7ccb8 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh @@ -53,7 +53,8 @@ struct TTCHeader; typedef struct TableRecord { - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -102,7 +103,8 @@ typedef struct OffsetTable } public: - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables)); } @@ -130,7 +132,8 @@ struct TTCHeaderVersion1 inline unsigned int get_face_count (void) const { return table.len; } inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (table.sanitize (c, this)); } @@ -169,7 +172,8 @@ struct TTCHeader } } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (unlikely (!u.header.version.sanitize (c))) return TRACE_RETURN (false); switch (u.header.version.major) { @@ -233,7 +237,8 @@ struct OpenTypeFontFile } } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (unlikely (!u.tag.sanitize (c))) return TRACE_RETURN (false); switch (u.tag) { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh index 477d9e28b2..75a0f568d1 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh @@ -179,10 +179,13 @@ struct hb_sanitize_context_t inline const char *get_name (void) { return "SANITIZE"; } static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE; typedef bool return_t; + template <typename T, typename F> + inline bool may_dispatch (const T *obj, const F *format) + { return format->sanitize (this); } template <typename T> inline return_t dispatch (const T &obj) { return obj.sanitize (this); } static return_t default_return_value (void) { return true; } - bool stop_sublookup_iteration (const return_t r HB_UNUSED) const { return false; } + bool stop_sublookup_iteration (const return_t r) const { return !r; } inline void init (hb_blob_t *b) { @@ -270,9 +273,9 @@ struct hb_sanitize_context_t } template <typename Type, typename ValueType> - inline bool try_set (Type *obj, const ValueType &v) { + inline bool try_set (const Type *obj, const ValueType &v) { if (this->may_edit (obj, obj->static_size)) { - obj->set (v); + const_cast<Type *> (obj)->set (v); return true; } return false; @@ -546,12 +549,6 @@ struct BEInt<Type, 2> return (v[0] << 8) + (v[1] ); } - inline bool operator == (const BEInt<Type, 2>& o) const - { - return v[0] == o.v[0] - && v[1] == o.v[1]; - } - inline bool operator != (const BEInt<Type, 2>& o) const { return !(*this == o); } private: uint8_t v[2]; }; template <typename Type> @@ -570,13 +567,6 @@ struct BEInt<Type, 3> + (v[1] << 8) + (v[2] ); } - inline bool operator == (const BEInt<Type, 3>& o) const - { - return v[0] == o.v[0] - && v[1] == o.v[1] - && v[2] == o.v[2]; - } - inline bool operator != (const BEInt<Type, 3>& o) const { return !(*this == o); } private: uint8_t v[3]; }; template <typename Type> @@ -597,14 +587,6 @@ struct BEInt<Type, 4> + (v[2] << 8) + (v[3] ); } - inline bool operator == (const BEInt<Type, 4>& o) const - { - return v[0] == o.v[0] - && v[1] == o.v[1] - && v[2] == o.v[2] - && v[3] == o.v[3]; - } - inline bool operator != (const BEInt<Type, 4>& o) const { return !(*this == o); } private: uint8_t v[4]; }; @@ -614,12 +596,19 @@ struct IntType { inline void set (Type i) { v.set (i); } inline operator Type(void) const { return v; } - inline bool operator == (const IntType<Type,Size> &o) const { return v == o.v; } - inline bool operator != (const IntType<Type,Size> &o) const { return v != o.v; } + inline bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; } + inline bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); } static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); } - inline int cmp (IntType<Type,Size> va) const { Type a = va; Type b = v; return a < b ? -1 : a == b ? 0 : +1; } - inline int cmp (Type a) const { Type b = v; return a < b ? -1 : a == b ? 0 : +1; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline int cmp (Type a) const + { + Type b = v; + if (sizeof (Type) < sizeof (int)) + return (int) a - (int) b; + else + return a < b ? -1 : a == b ? 0 : +1; + } + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (likely (c->check_struct (this))); } @@ -646,7 +635,8 @@ typedef USHORT UFWORD; * 1904. The value is represented as a signed 64-bit integer. */ struct LONGDATETIME { - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (likely (c->check_struct (this))); } @@ -670,7 +660,10 @@ struct Tag : ULONG DEFINE_NULL_DATA (Tag, " "); /* Glyph index number, same as uint16 (length = 16 bits) */ -typedef USHORT GlyphID; +struct GlyphID : USHORT { + static inline int cmp (const GlyphID *a, const GlyphID *b) { return b->USHORT::cmp (*a); } + inline int cmp (hb_codepoint_t a) const { return (int) a - (int) *this; } +}; /* Script/language-system/feature index */ struct Index : USHORT { @@ -719,7 +712,8 @@ struct FixedVersion { inline uint32_t to_int (void) const { return (major << 16) + minor; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -747,33 +741,35 @@ struct OffsetTo : Offset<OffsetType> return StructAtOffset<Type> (base, offset); } - inline Type& serialize (hb_serialize_context_t *c, void *base) + inline Type& serialize (hb_serialize_context_t *c, const void *base) { Type *t = c->start_embed<Type> (); this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */ return *t; } - inline bool sanitize (hb_sanitize_context_t *c, void *base) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); unsigned int offset = *this; if (unlikely (!offset)) return TRACE_RETURN (true); - Type &obj = StructAtOffset<Type> (base, offset); + const Type &obj = StructAtOffset<Type> (base, offset); return TRACE_RETURN (likely (obj.sanitize (c)) || neuter (c)); } template <typename T> - inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const + { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); unsigned int offset = *this; if (unlikely (!offset)) return TRACE_RETURN (true); - Type &obj = StructAtOffset<Type> (base, offset); + const Type &obj = StructAtOffset<Type> (base, offset); return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c)); } /* Set the offset to Null */ - inline bool neuter (hb_sanitize_context_t *c) { + inline bool neuter (hb_sanitize_context_t *c) const { return c->try_set (this, 0); } DEFINE_SIZE_STATIC (sizeof(OffsetType)); @@ -838,7 +834,8 @@ struct ArrayOf return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); @@ -853,7 +850,8 @@ struct ArrayOf return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c, void *base) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); unsigned int count = len; @@ -863,7 +861,8 @@ struct ArrayOf return TRACE_RETURN (true); } template <typename T> - inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const + { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); unsigned int count = len; @@ -884,7 +883,8 @@ struct ArrayOf } private: - inline bool sanitize_shallow (hb_sanitize_context_t *c) { + inline bool sanitize_shallow (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::static_size, len)); } @@ -910,12 +910,14 @@ struct OffsetListOf : OffsetArrayOf<Type> return this+this->array[i]; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this)); } template <typename T> - inline bool sanitize (hb_sanitize_context_t *c, T user_data) { + inline bool sanitize (hb_sanitize_context_t *c, T user_data) const + { TRACE_SANITIZE (this); return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this, user_data)); } @@ -949,12 +951,14 @@ struct HeadlessArrayOf return TRACE_RETURN (true); } - inline bool sanitize_shallow (hb_sanitize_context_t *c) { + inline bool sanitize_shallow (hb_sanitize_context_t *c) const + { return c->check_struct (this) && c->check_array (this, Type::static_size, len); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh index d53141157d..0482312553 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh @@ -51,7 +51,8 @@ struct CmapSubtableFormat0 return true; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -125,7 +126,7 @@ struct CmapSubtableFormat4 return true; } - inline bool sanitize (hb_sanitize_context_t *c) + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) @@ -183,7 +184,8 @@ struct CmapSubtableLongGroup return 0; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -210,7 +212,8 @@ struct CmapSubtableTrimmed return true; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && glyphIdArray.sanitize (c)); } @@ -242,7 +245,8 @@ struct CmapSubtableLongSegmented return true; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && groups.sanitize (c)); } @@ -288,7 +292,8 @@ struct UnicodeValueRange return 0; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -309,7 +314,8 @@ struct UVSMapping return unicodeValue.cmp (codepoint); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -348,7 +354,8 @@ struct VariationSelectorRecord return varSelector.cmp (variation_selector); } - inline bool sanitize (hb_sanitize_context_t *c, void *base) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && defaultUVS.sanitize (c, base) && @@ -373,7 +380,8 @@ struct CmapSubtableFormat14 return record[record.bsearch(variation_selector)].get_glyph (codepoint, glyph, this); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && record.sanitize (c, this)); @@ -418,7 +426,8 @@ struct CmapSubtable } } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return TRACE_RETURN (false); switch (u.format) { @@ -461,7 +470,8 @@ struct EncodingRecord return 0; } - inline bool sanitize (hb_sanitize_context_t *c, void *base) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && subtable.sanitize (c, base)); @@ -496,7 +506,8 @@ struct cmap return &(this+encodingRecord[result].subtable); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && likely (version == 0) && diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh index ec4e8c9d45..268f133408 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh @@ -45,13 +45,15 @@ struct head { static const hb_tag_t tableTag = HB_OT_TAG_head; - inline unsigned int get_upem (void) const { + inline unsigned int get_upem (void) const + { unsigned int upem = unitsPerEm; /* If no valid head table found, assume 1000, which matches typical Type1 usage. */ return 16 <= upem && upem <= 16384 ? upem : 1000; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1)); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh index edc0e29cbf..992fe55202 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh @@ -49,7 +49,8 @@ struct _hea static const hb_tag_t hheaTag = HB_OT_TAG_hhea; static const hb_tag_t vheaTag = HB_OT_TAG_vhea; - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1)); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh index 317854ce7f..a0e3855a84 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh @@ -57,7 +57,8 @@ struct _mtx static const hb_tag_t hmtxTag = HB_OT_TAG_hmtx; static const hb_tag_t vmtxTag = HB_OT_TAG_vmtx; - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); /* We don't check for anything specific here. The users of the * struct do all the hard work... */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh index abd063c896..3db7f57ab4 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh @@ -37,6 +37,12 @@ namespace OT { +#define TRACE_DISPATCH(this, format) \ + hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \ + (&c->debug_depth, c->get_name (), this, HB_FUNC, \ + "format %d", (int) format); + + #define NOT_COVERED ((unsigned int) -1) #define MAX_NESTING_LEVEL 8 #define MAX_CONTEXT_LENGTH 64 @@ -63,9 +69,10 @@ struct Record struct sanitize_closure_t { hb_tag_t tag; - void *list_base; + const void *list_base; }; - inline bool sanitize (hb_sanitize_context_t *c, void *base) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { TRACE_SANITIZE (this); const sanitize_closure_t closure = {tag, base}; return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base, &closure)); @@ -121,7 +128,8 @@ struct RecordListOf : RecordArrayOf<Type> inline const Type& operator [] (unsigned int i) const { return this+RecordArrayOf<Type>::operator [](i).offset; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this)); } @@ -134,7 +142,8 @@ struct RangeRecord return g < start ? -1 : g <= end ? 0 : +1 ; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -199,7 +208,8 @@ struct LangSys } inline bool sanitize (hb_sanitize_context_t *c, - const Record<LangSys>::sanitize_closure_t * = NULL) { + const Record<LangSys>::sanitize_closure_t * = NULL) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c)); } @@ -238,7 +248,8 @@ struct Script inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; } inline bool sanitize (hb_sanitize_context_t *c, - const Record<Script>::sanitize_closure_t * = NULL) { + const Record<Script>::sanitize_closure_t * = NULL) const + { TRACE_SANITIZE (this); return TRACE_RETURN (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this)); } @@ -260,7 +271,8 @@ typedef RecordListOf<Script> ScriptList; /* http://www.microsoft.com/typography/otspec/features_pt.htm#size */ struct FeatureParamsSize { - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); @@ -371,7 +383,8 @@ struct FeatureParamsSize /* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */ struct FeatureParamsStylisticSet { - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); /* Right now minorVersion is at zero. Which means, any table supports * the uiNameID field. */ @@ -404,7 +417,8 @@ struct FeatureParamsStylisticSet /* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */ struct FeatureParamsCharacterVariants { - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && characters.sanitize (c)); @@ -444,7 +458,8 @@ struct FeatureParamsCharacterVariants struct FeatureParams { - inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) { + inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) const + { TRACE_SANITIZE (this); if (tag == HB_TAG ('s','i','z','e')) return TRACE_RETURN (u.size.sanitize (c)); @@ -486,7 +501,8 @@ struct Feature { return this+featureParams; } inline bool sanitize (hb_sanitize_context_t *c, - const Record<Feature>::sanitize_closure_t *closure) { + const Record<Feature>::sanitize_closure_t *closure) const + { TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) return TRACE_RETURN (false); @@ -561,6 +577,17 @@ struct Lookup { inline unsigned int get_subtable_count (void) const { return subTable.len; } + template <typename SubTableType> + inline const SubTableType& get_subtable (unsigned int i) const + { return this+CastR<OffsetArrayOf<SubTableType> > (subTable)[i]; } + + template <typename SubTableType> + inline const OffsetArrayOf<SubTableType>& get_subtables (void) const + { return CastR<OffsetArrayOf<SubTableType> > (subTable); } + template <typename SubTableType> + inline OffsetArrayOf<SubTableType>& get_subtables (void) + { return CastR<OffsetArrayOf<SubTableType> > (subTable); } + inline unsigned int get_type (void) const { return lookupType; } /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and @@ -577,6 +604,20 @@ struct Lookup return flag; } + template <typename SubTableType, typename context_t> + inline typename context_t::return_t dispatch (context_t *c) const + { + unsigned int lookup_type = get_type (); + TRACE_DISPATCH (this, lookup_type); + unsigned int count = get_subtable_count (); + for (unsigned int i = 0; i < count; i++) { + typename context_t::return_t r = get_subtable<SubTableType> (i).dispatch (c, lookup_type); + if (c->stop_sublookup_iteration (r)) + return TRACE_RETURN (r); + } + return TRACE_RETURN (c->default_return_value ()); + } + inline bool serialize (hb_serialize_context_t *c, unsigned int lookup_type, uint32_t lookup_props, @@ -595,18 +636,20 @@ struct Lookup return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); /* Real sanitize of the subtables is done by GSUB/GPOS/... */ if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN (false); if (lookupFlag & LookupFlag::UseMarkFilteringSet) { - USHORT &markFilteringSet = StructAfter<USHORT> (subTable); + const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false); } return TRACE_RETURN (true); } + private: USHORT lookupType; /* Different enumerations for GSUB and GPOS */ USHORT lookupFlag; /* Lookup qualifiers */ ArrayOf<Offset<> > @@ -651,7 +694,8 @@ struct CoverageFormat1 return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (glyphArray.sanitize (c)); } @@ -737,7 +781,8 @@ struct CoverageFormat2 return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (rangeRecord.sanitize (c)); } @@ -832,7 +877,8 @@ struct Coverage } } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return TRACE_RETURN (false); switch (u.format) { @@ -938,12 +984,14 @@ struct ClassDefFormat1 private: inline unsigned int get_class (hb_codepoint_t glyph_id) const { - if (unlikely ((unsigned int) (glyph_id - startGlyph) < classValue.len)) - return classValue[glyph_id - startGlyph]; + unsigned int i = (unsigned int) (glyph_id - startGlyph); + if (unlikely (i < classValue.len)) + return classValue[i]; return 0; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && classValue.sanitize (c)); } @@ -994,12 +1042,13 @@ struct ClassDefFormat2 inline unsigned int get_class (hb_codepoint_t glyph_id) const { int i = rangeRecord.bsearch (glyph_id); - if (i != -1) + if (unlikely (i != -1)) return rangeRecord[i].value; return 0; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (rangeRecord.sanitize (c)); } @@ -1056,7 +1105,8 @@ struct ClassDef } } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return TRACE_RETURN (false); switch (u.format) { @@ -1148,7 +1198,8 @@ struct Device return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f))); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->get_size ())); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh index 84a5e797c6..7a6c04d170 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh @@ -71,7 +71,8 @@ struct AttachList return points.len; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (coverage.sanitize (c, this) && attachPoint.sanitize (c, this)); } @@ -101,7 +102,8 @@ struct CaretValueFormat1 return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -127,7 +129,8 @@ struct CaretValueFormat2 return 0; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -150,7 +153,8 @@ struct CaretValueFormat3 font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && deviceTable.sanitize (c, this)); } @@ -178,7 +182,8 @@ struct CaretValue } } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return TRACE_RETURN (false); switch (u.format) { @@ -219,7 +224,8 @@ struct LigGlyph return carets.len; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (carets.sanitize (c, this)); } @@ -253,7 +259,8 @@ struct LigCaretList return lig_glyph.get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this)); } @@ -275,7 +282,8 @@ struct MarkGlyphSetsFormat1 inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (coverage.sanitize (c, this)); } @@ -299,7 +307,8 @@ struct MarkGlyphSets } } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return TRACE_RETURN (false); switch (u.format) { @@ -364,7 +373,8 @@ struct GDEF inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const { return version.to_int () >= 0x00010002u && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) && diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh index f7fef5273a..d88f7876e0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh @@ -146,7 +146,8 @@ struct ValueFormat : USHORT } private: - inline bool sanitize_value_devices (hb_sanitize_context_t *c, void *base, Value *values) { + inline bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const + { unsigned int format = *this; if (format & xPlacement) values++; @@ -177,12 +178,14 @@ struct ValueFormat : USHORT return (format & devices) != 0; } - inline bool sanitize_value (hb_sanitize_context_t *c, void *base, Value *values) { + inline bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values))); } - inline bool sanitize_values (hb_sanitize_context_t *c, void *base, Value *values, unsigned int count) { + inline bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const + { TRACE_SANITIZE (this); unsigned int len = get_len (); @@ -200,7 +203,8 @@ struct ValueFormat : USHORT } /* Just sanitize referenced Device tables. Doesn't check the values themselves. */ - inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, void *base, Value *values, unsigned int count, unsigned int stride) { + inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count, unsigned int stride) const + { TRACE_SANITIZE (this); if (!has_device ()) return TRACE_RETURN (true); @@ -225,7 +229,8 @@ struct AnchorFormat1 *y = font->em_scale_y (yCoordinate); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -254,7 +259,8 @@ struct AnchorFormat2 *y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -282,7 +288,8 @@ struct AnchorFormat3 *y += (this+yDeviceTable).get_x_delta (font); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this)); } @@ -317,7 +324,8 @@ struct Anchor } } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return TRACE_RETURN (false); switch (u.format) { @@ -349,7 +357,8 @@ struct AnchorMatrix return this+matrixZ[row * cols + col]; } - inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) { + inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const + { TRACE_SANITIZE (this); if (!c->check_struct (this)) return TRACE_RETURN (false); if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_RETURN (false); @@ -374,7 +383,8 @@ struct MarkRecord { friend struct MarkArray; - inline bool sanitize (hb_sanitize_context_t *c, void *base) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base)); } @@ -421,7 +431,8 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this)); } @@ -457,9 +468,12 @@ struct SinglePosFormat1 return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_value (c, this, values)); + return TRACE_RETURN (c->check_struct (this) + && coverage.sanitize (c, this) + && valueFormat.sanitize_value (c, this, values)); } protected: @@ -506,9 +520,12 @@ struct SinglePosFormat2 return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_values (c, this, values, valueCount)); + return TRACE_RETURN (c->check_struct (this) + && coverage.sanitize (c, this) + && valueFormat.sanitize_values (c, this, values, valueCount)); } protected: @@ -531,6 +548,7 @@ struct SinglePos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); switch (u.format) { case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 2: return TRACE_RETURN (c->dispatch (u.format2)); @@ -538,16 +556,6 @@ struct SinglePos } } - inline bool sanitize (hb_sanitize_context_t *c) { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - case 2: return TRACE_RETURN (u.format2.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -636,19 +644,20 @@ struct PairSet } struct sanitize_closure_t { - void *base; - ValueFormat *valueFormats; + const void *base; + const ValueFormat *valueFormats; unsigned int len1; /* valueFormats[0].get_len() */ unsigned int stride; /* 1 + len1 + len2 */ }; - inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) { + inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const + { TRACE_SANITIZE (this); if (!(c->check_struct (this) && c->check_array (arrayZ, USHORT::static_size * closure->stride, len))) return TRACE_RETURN (false); unsigned int count = len; - PairValueRecord *record = CastP<PairValueRecord> (arrayZ); + const PairValueRecord *record = CastP<PairValueRecord> (arrayZ); return TRACE_RETURN (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) && closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride)); } @@ -681,18 +690,18 @@ struct PairPosFormat1 { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; - hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1); - if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); - unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + skippy_iter.reset (buffer->idx, 1); if (!skippy_iter.next ()) return TRACE_RETURN (false); return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx)); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); unsigned int len1 = valueFormat1.get_len (); @@ -752,12 +761,11 @@ struct PairPosFormat2 { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; - hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1); - if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); - unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + skippy_iter.reset (buffer->idx, 1); if (!skippy_iter.next ()) return TRACE_RETURN (false); unsigned int len1 = valueFormat1.get_len (); @@ -781,7 +789,8 @@ struct PairPosFormat2 return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (!(c->check_struct (this) && coverage.sanitize (c, this) @@ -834,6 +843,7 @@ struct PairPos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); switch (u.format) { case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 2: return TRACE_RETURN (c->dispatch (u.format2)); @@ -841,16 +851,6 @@ struct PairPos } } - inline bool sanitize (hb_sanitize_context_t *c) { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - case 2: return TRACE_RETURN (u.format2.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -864,7 +864,8 @@ struct EntryExitRecord { friend struct CursivePosFormat1; - inline bool sanitize (hb_sanitize_context_t *c, void *base) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { TRACE_SANITIZE (this); return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base)); } @@ -903,12 +904,11 @@ struct CursivePosFormat1 /* We don't handle mark glyphs here. */ if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return TRACE_RETURN (false); - hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1); - if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); - const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)]; if (!this_record.exitAnchor) return TRACE_RETURN (false); + hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + skippy_iter.reset (buffer->idx, 1); if (!skippy_iter.next ()) return TRACE_RETURN (false); const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)]; @@ -978,7 +978,8 @@ struct CursivePosFormat1 return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this)); } @@ -1001,21 +1002,13 @@ struct CursivePos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); switch (u.format) { case 1: return TRACE_RETURN (c->dispatch (u.format1)); default:return TRACE_RETURN (c->default_return_value ()); } } - inline bool sanitize (hb_sanitize_context_t *c) { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -1051,7 +1044,8 @@ struct MarkBasePosFormat1 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); /* now we search backwards for a non-mark glyph */ - hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1); + hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + skippy_iter.reset (buffer->idx, 1); skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); do { if (!skippy_iter.prev ()) return TRACE_RETURN (false); @@ -1069,7 +1063,8 @@ struct MarkBasePosFormat1 return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx)); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && baseCoverage.sanitize (c, this) && markArray.sanitize (c, this) && baseArray.sanitize (c, this, (unsigned int) classCount)); @@ -1100,21 +1095,13 @@ struct MarkBasePos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); switch (u.format) { case 1: return TRACE_RETURN (c->dispatch (u.format1)); default:return TRACE_RETURN (c->default_return_value ()); } } - inline bool sanitize (hb_sanitize_context_t *c) { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -1155,7 +1142,8 @@ struct MarkLigPosFormat1 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); /* now we search backwards for a non-mark glyph */ - hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1); + hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + skippy_iter.reset (buffer->idx, 1); skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); if (!skippy_iter.prev ()) return TRACE_RETURN (false); @@ -1189,7 +1177,8 @@ struct MarkLigPosFormat1 return TRACE_RETURN ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j)); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && ligatureCoverage.sanitize (c, this) && markArray.sanitize (c, this) && ligatureArray.sanitize (c, this, (unsigned int) classCount)); @@ -1221,21 +1210,13 @@ struct MarkLigPos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); switch (u.format) { case 1: return TRACE_RETURN (c->dispatch (u.format1)); default:return TRACE_RETURN (c->default_return_value ()); } } - inline bool sanitize (hb_sanitize_context_t *c) { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -1271,7 +1252,8 @@ struct MarkMarkPosFormat1 if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false); /* now we search backwards for a suitable mark glyph until a non-mark glyph */ - hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1); + hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + skippy_iter.reset (buffer->idx, 1); skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags); if (!skippy_iter.prev ()) return TRACE_RETURN (false); @@ -1306,7 +1288,8 @@ struct MarkMarkPosFormat1 return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j)); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, this) && mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this) @@ -1340,21 +1323,13 @@ struct MarkMarkPos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); switch (u.format) { case 1: return TRACE_RETURN (c->dispatch (u.format1)); default:return TRACE_RETURN (c->default_return_value ()); } } - inline bool sanitize (hb_sanitize_context_t *c) { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -1399,6 +1374,8 @@ struct PosLookupSubTable inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const { TRACE_DISPATCH (this, lookup_type); + /* The sub_format passed to may_dispatch is unnecessary but harmless. */ + if (unlikely (!c->may_dispatch (this, &u.sub_format))) TRACE_RETURN (c->default_return_value ()); switch (lookup_type) { case Single: return TRACE_RETURN (u.single.dispatch (c)); case Pair: return TRACE_RETURN (u.pair.dispatch (c)); @@ -1413,29 +1390,9 @@ struct PosLookupSubTable } } - inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) { - TRACE_SANITIZE (this); - if (!u.header.sub_format.sanitize (c)) - return TRACE_RETURN (false); - switch (lookup_type) { - case Single: return TRACE_RETURN (u.single.sanitize (c)); - case Pair: return TRACE_RETURN (u.pair.sanitize (c)); - case Cursive: return TRACE_RETURN (u.cursive.sanitize (c)); - case MarkBase: return TRACE_RETURN (u.markBase.sanitize (c)); - case MarkLig: return TRACE_RETURN (u.markLig.sanitize (c)); - case MarkMark: return TRACE_RETURN (u.markMark.sanitize (c)); - case Context: return TRACE_RETURN (u.context.sanitize (c)); - case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c)); - case Extension: return TRACE_RETURN (u.extension.sanitize (c)); - default: return TRACE_RETURN (true); - } - } - protected: union { - struct { - USHORT sub_format; - } header; + USHORT sub_format; SinglePos single; PairPos pair; CursivePos cursive; @@ -1447,48 +1404,37 @@ struct PosLookupSubTable ExtensionPos extension; } u; public: - DEFINE_SIZE_UNION (2, header.sub_format); + DEFINE_SIZE_UNION (2, sub_format); }; struct PosLookup : Lookup { inline const PosLookupSubTable& get_subtable (unsigned int i) const - { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; } + { return Lookup::get_subtable<PosLookupSubTable> (i); } inline bool is_reverse (void) const { return false; } + inline bool apply (hb_apply_context_t *c) const + { + TRACE_APPLY (this); + return TRACE_RETURN (dispatch (c)); + } + inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - c->set_recurse_func (NULL); return TRACE_RETURN (dispatch (c)); } template <typename set_t> inline void add_coverage (set_t *glyphs) const { - hb_get_coverage_context_t c; - const Coverage *last = NULL; - unsigned int count = get_subtable_count (); - for (unsigned int i = 0; i < count; i++) { - const Coverage *coverage = &get_subtable (i).dispatch (&c, get_type ()); - if (coverage != last) { - coverage->add_coverage (glyphs); - last = coverage; - } - } - } - - inline bool apply_once (hb_apply_context_t *c) const - { - TRACE_APPLY (this); - if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) - return TRACE_RETURN (false); - return TRACE_RETURN (dispatch (c)); + hb_add_coverage_context_t<set_t> c (glyphs); + dispatch (&c); } static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index); @@ -1498,23 +1444,14 @@ struct PosLookup : Lookup template <typename context_t> inline typename context_t::return_t dispatch (context_t *c) const - { - unsigned int lookup_type = get_type (); - TRACE_DISPATCH (this, lookup_type); - unsigned int count = get_subtable_count (); - for (unsigned int i = 0; i < count; i++) { - typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type); - if (c->stop_sublookup_iteration (r)) - return TRACE_RETURN (r); - } - return TRACE_RETURN (c->default_return_value ()); - } + { return Lookup::dispatch<PosLookupSubTable> (c); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); - OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTable> > (subTable); - return TRACE_RETURN (list.sanitize (c, this, get_type ())); + const OffsetArrayOf<PosLookupSubTable> &list = get_subtables<PosLookupSubTable> (); + return TRACE_RETURN (dispatch (c)); } }; @@ -1534,10 +1471,11 @@ struct GPOS : GSUBGPOS static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer); - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); - OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList); + const OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList); return TRACE_RETURN (list.sanitize (c, this)); } public: @@ -1632,8 +1570,8 @@ template <typename context_t> const PosLookup &l = gpos.get_lookup (lookup_index); unsigned int saved_lookup_props = c->lookup_props; c->set_lookup (l); - bool ret = l.apply_once (c); - c->lookup_props = saved_lookup_props; + bool ret = l.dispatch (c); + c->set_lookup_props (saved_lookup_props); return ret; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh index 5d67be0ec0..ebe4c9ec4e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh @@ -97,7 +97,8 @@ struct SingleSubstFormat1 return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c)); } @@ -173,7 +174,8 @@ struct SingleSubstFormat2 return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (coverage.sanitize (c, this) && substitute.sanitize (c)); } @@ -223,6 +225,7 @@ struct SingleSubst inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); switch (u.format) { case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 2: return TRACE_RETURN (c->dispatch (u.format2)); @@ -230,16 +233,6 @@ struct SingleSubst } } - inline bool sanitize (hb_sanitize_context_t *c) { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - case 2: return TRACE_RETURN (u.format2.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -312,7 +305,8 @@ struct Sequence return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (substitute.sanitize (c)); } @@ -384,7 +378,8 @@ struct MultipleSubstFormat1 return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (coverage.sanitize (c, this) && sequence.sanitize (c, this)); } @@ -423,21 +418,13 @@ struct MultipleSubst inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); switch (u.format) { case 1: return TRACE_RETURN (c->dispatch (u.format1)); default:return TRACE_RETURN (c->default_return_value ()); } } - inline bool sanitize (hb_sanitize_context_t *c) { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -535,7 +522,8 @@ struct AlternateSubstFormat1 return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (coverage.sanitize (c, this) && alternateSet.sanitize (c, this)); } @@ -574,21 +562,13 @@ struct AlternateSubst inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); switch (u.format) { case 1: return TRACE_RETURN (c->dispatch (u.format1)); default:return TRACE_RETURN (c->default_return_value ()); } } - inline bool sanitize (hb_sanitize_context_t *c) { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -686,7 +666,8 @@ struct Ligature } public: - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (ligGlyph.sanitize (c) && component.sanitize (c)); } @@ -764,7 +745,8 @@ struct LigatureSet return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (ligature.sanitize (c, this)); } @@ -848,7 +830,8 @@ struct LigatureSubstFormat1 return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this)); } @@ -890,21 +873,13 @@ struct LigatureSubst inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); switch (u.format) { case 1: return TRACE_RETURN (c->dispatch (u.format1)); default:return TRACE_RETURN (c->default_return_value ()); } } - inline bool sanitize (hb_sanitize_context_t *c) { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -1017,14 +992,15 @@ struct ReverseChainSingleSubstFormat1 return TRACE_RETURN (false); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) return TRACE_RETURN (false); - OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); + const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false); - ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); + const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); return TRACE_RETURN (substitute.sanitize (c)); } @@ -1054,21 +1030,13 @@ struct ReverseChainSingleSubst inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); switch (u.format) { case 1: return TRACE_RETURN (c->dispatch (u.format1)); default:return TRACE_RETURN (c->default_return_value ()); } } - inline bool sanitize (hb_sanitize_context_t *c) { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -1101,6 +1069,8 @@ struct SubstLookupSubTable inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const { TRACE_DISPATCH (this, lookup_type); + /* The sub_format passed to may_dispatch is unnecessary but harmless. */ + if (unlikely (!c->may_dispatch (this, &u.sub_format))) TRACE_RETURN (c->default_return_value ()); switch (lookup_type) { case Single: return TRACE_RETURN (u.single.dispatch (c)); case Multiple: return TRACE_RETURN (u.multiple.dispatch (c)); @@ -1114,28 +1084,9 @@ struct SubstLookupSubTable } } - inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) { - TRACE_SANITIZE (this); - if (!u.header.sub_format.sanitize (c)) - return TRACE_RETURN (false); - switch (lookup_type) { - case Single: return TRACE_RETURN (u.single.sanitize (c)); - case Multiple: return TRACE_RETURN (u.multiple.sanitize (c)); - case Alternate: return TRACE_RETURN (u.alternate.sanitize (c)); - case Ligature: return TRACE_RETURN (u.ligature.sanitize (c)); - case Context: return TRACE_RETURN (u.context.sanitize (c)); - case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c)); - case Extension: return TRACE_RETURN (u.extension.sanitize (c)); - case ReverseChainSingle: return TRACE_RETURN (u.reverseChainContextSingle.sanitize (c)); - default: return TRACE_RETURN (true); - } - } - protected: union { - struct { - USHORT sub_format; - } header; + USHORT sub_format; SingleSubst single; MultipleSubst multiple; AlternateSubst alternate; @@ -1146,14 +1097,14 @@ struct SubstLookupSubTable ReverseChainSingleSubst reverseChainContextSingle; } u; public: - DEFINE_SIZE_UNION (2, header.sub_format); + DEFINE_SIZE_UNION (2, sub_format); }; struct SubstLookup : Lookup { inline const SubstLookupSubTable& get_subtable (unsigned int i) const - { return this+CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable)[i]; } + { return Lookup::get_subtable<SubstLookupSubTable> (i); } inline static bool lookup_type_is_reverse (unsigned int lookup_type) { return lookup_type == SubstLookupSubTable::ReverseChainSingle; } @@ -1166,6 +1117,12 @@ struct SubstLookup : Lookup return lookup_type_is_reverse (type); } + inline bool apply (hb_apply_context_t *c) const + { + TRACE_APPLY (this); + return TRACE_RETURN (dispatch (c)); + } + inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); @@ -1183,39 +1140,24 @@ struct SubstLookup : Lookup template <typename set_t> inline void add_coverage (set_t *glyphs) const { - hb_get_coverage_context_t c; - const Coverage *last = NULL; - unsigned int count = get_subtable_count (); - for (unsigned int i = 0; i < count; i++) { - const Coverage *coverage = &get_subtable (i).dispatch (&c, get_type ()); - if (coverage != last) { - coverage->add_coverage (glyphs); - last = coverage; - } - } + hb_add_coverage_context_t<set_t> c (glyphs); + dispatch (&c); } - inline bool would_apply (hb_would_apply_context_t *c, const hb_set_digest_t *digest) const + inline bool would_apply (hb_would_apply_context_t *c, + const hb_ot_layout_lookup_accelerator_t *accel) const { TRACE_WOULD_APPLY (this); if (unlikely (!c->len)) return TRACE_RETURN (false); - if (!digest->may_have (c->glyphs[0])) return TRACE_RETURN (false); + if (!accel->may_have (c->glyphs[0])) return TRACE_RETURN (false); return TRACE_RETURN (dispatch (c)); } - inline bool apply_once (hb_apply_context_t *c) const - { - TRACE_APPLY (this); - if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) - return TRACE_RETURN (false); - return TRACE_RETURN (dispatch (c)); - } - static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index); inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c, unsigned int i) - { return CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable)[i].serialize (c, this); } + { return get_subtables<SubstLookupSubTable> ()[i].serialize (c, this); } inline bool serialize_single (hb_serialize_context_t *c, uint32_t lookup_props, @@ -1274,24 +1216,14 @@ struct SubstLookup : Lookup template <typename context_t> inline typename context_t::return_t dispatch (context_t *c) const - { - unsigned int lookup_type = get_type (); - TRACE_DISPATCH (this, lookup_type); - unsigned int count = get_subtable_count (); - for (unsigned int i = 0; i < count; i++) { - typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type); - if (c->stop_sublookup_iteration (r)) - return TRACE_RETURN (r); - } - return TRACE_RETURN (c->default_return_value ()); - } + { return Lookup::dispatch<SubstLookupSubTable> (c); } - inline bool sanitize (hb_sanitize_context_t *c) + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); - OffsetArrayOf<SubstLookupSubTable> &list = CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable); - if (unlikely (!list.sanitize (c, this, get_type ()))) return TRACE_RETURN (false); + const OffsetArrayOf<SubstLookupSubTable> &list = get_subtables<SubstLookupSubTable> (); + if (unlikely (!dispatch (c))) return TRACE_RETURN (false); if (unlikely (get_type () == SubstLookupSubTable::Extension)) { @@ -1324,10 +1256,11 @@ struct GSUB : GSUBGPOS static inline void substitute_start (hb_font_t *font, hb_buffer_t *buffer); static inline void substitute_finish (hb_font_t *font, hb_buffer_t *buffer); - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); - OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupList); + const OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupList); return TRACE_RETURN (list.sanitize (c, this)); } public: @@ -1362,7 +1295,7 @@ GSUB::substitute_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSE { unsigned int type = get_type (); if (unlikely (type == SubstLookupSubTable::Extension)) - return CastR<ExtensionSubst> (get_subtable<SubstLookupSubTable>()).is_reverse (); + return CastR<ExtensionSubst> (get_subtable<LookupSubTable>()).is_reverse (); return SubstLookup::lookup_type_is_reverse (type); } @@ -1380,8 +1313,8 @@ template <typename context_t> const SubstLookup &l = gsub.get_lookup (lookup_index); unsigned int saved_lookup_props = c->lookup_props; c->set_lookup (l); - bool ret = l.apply_once (c); - c->lookup_props = saved_lookup_props; + bool ret = l.dispatch (c); + c->set_lookup_props (saved_lookup_props); return ret; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh index 57fc1e05f7..cbc6840bc8 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh @@ -37,12 +37,6 @@ namespace OT { - -#define TRACE_DISPATCH(this, format) \ - hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \ - (&c->debug_depth, c->get_name (), this, HB_FUNC, \ - "format %d", (int) format); - #ifndef HB_DEBUG_CLOSURE #define HB_DEBUG_CLOSURE (HB_DEBUG+0) #endif @@ -58,6 +52,8 @@ struct hb_closure_context_t static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE; typedef hb_void_t return_t; typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index); + template <typename T, typename F> + inline bool may_dispatch (const T *obj, const F *format) { return true; } template <typename T> inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; } static return_t default_return_value (void) { return HB_VOID; } @@ -107,6 +103,8 @@ struct hb_would_apply_context_t inline const char *get_name (void) { return "WOULD_APPLY"; } static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY; typedef bool return_t; + template <typename T, typename F> + inline bool may_dispatch (const T *obj, const F *format) { return true; } template <typename T> inline return_t dispatch (const T &obj) { return obj.would_apply (this); } static return_t default_return_value (void) { return false; } @@ -146,6 +144,8 @@ struct hb_collect_glyphs_context_t static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS; typedef hb_void_t return_t; typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index); + template <typename T, typename F> + inline bool may_dispatch (const T *obj, const F *format) { return true; } template <typename T> inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; } static return_t default_return_value (void) { return HB_VOID; } @@ -232,18 +232,28 @@ struct hb_collect_glyphs_context_t #define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0) #endif -struct hb_get_coverage_context_t +template <typename set_t> +struct hb_add_coverage_context_t { inline const char *get_name (void) { return "GET_COVERAGE"; } static const unsigned int max_debug_depth = HB_DEBUG_GET_COVERAGE; typedef const Coverage &return_t; + template <typename T, typename F> + inline bool may_dispatch (const T *obj, const F *format) { return true; } template <typename T> inline return_t dispatch (const T &obj) { return obj.get_coverage (); } static return_t default_return_value (void) { return Null(Coverage); } + bool stop_sublookup_iteration (return_t r) const + { + r.add_coverage (set); + return false; + } - hb_get_coverage_context_t (void) : + hb_add_coverage_context_t (set_t *set_) : + set (set_), debug_depth (0) {} + set_t *set; unsigned int debug_depth; }; @@ -260,61 +270,6 @@ struct hb_get_coverage_context_t struct hb_apply_context_t { - inline const char *get_name (void) { return "APPLY"; } - static const unsigned int max_debug_depth = HB_DEBUG_APPLY; - typedef bool return_t; - typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index); - template <typename T> - inline return_t dispatch (const T &obj) { return obj.apply (this); } - static return_t default_return_value (void) { return false; } - bool stop_sublookup_iteration (return_t r) const { return r; } - return_t recurse (unsigned int lookup_index) - { - if (unlikely (nesting_level_left == 0 || !recurse_func)) - return default_return_value (); - - nesting_level_left--; - bool ret = recurse_func (this, lookup_index); - nesting_level_left++; - return ret; - } - - unsigned int table_index; /* GSUB/GPOS */ - hb_font_t *font; - hb_face_t *face; - hb_buffer_t *buffer; - hb_direction_t direction; - hb_mask_t lookup_mask; - bool auto_zwj; - recurse_func_t recurse_func; - unsigned int nesting_level_left; - unsigned int lookup_props; - const GDEF &gdef; - bool has_glyph_classes; - unsigned int debug_depth; - - - hb_apply_context_t (unsigned int table_index_, - hb_font_t *font_, - hb_buffer_t *buffer_) : - table_index (table_index_), - font (font_), face (font->face), buffer (buffer_), - direction (buffer_->props.direction), - lookup_mask (1), - auto_zwj (true), - recurse_func (NULL), - nesting_level_left (MAX_NESTING_LEVEL), - lookup_props (0), - gdef (*hb_ot_layout_from_face (face)->gdef), - has_glyph_classes (gdef.has_glyph_classes ()), - debug_depth (0) {} - - inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; } - inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; } - inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } - inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } - inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); } - struct matcher_t { inline matcher_t (void) : @@ -390,29 +345,24 @@ struct hb_apply_context_t const void *match_data; }; - struct skipping_forward_iterator_t - { - inline skipping_forward_iterator_t (hb_apply_context_t *c_, - unsigned int start_index_, - unsigned int num_items_, - bool context_match = false) : - idx (start_index_), - c (c_), - match_glyph_data (NULL), - num_items (num_items_), - end (c->buffer->len) + struct skipping_iterator_t + { + inline void init (hb_apply_context_t *c_, bool context_match = false) { + c = c_; + match_glyph_data = NULL, + matcher.set_match_func (NULL, NULL); matcher.set_lookup_props (c->lookup_props); /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ matcher.set_ignore_zwnj (context_match || c->table_index == 1); /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj); - if (!context_match) - matcher.set_mask (c->lookup_mask); - matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); + matcher.set_mask (context_match ? -1 : c->lookup_mask); + } + inline void set_lookup_props (unsigned int lookup_props) + { + matcher.set_lookup_props (lookup_props); } - inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); } - inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); } inline void set_match_func (matcher_t::match_func_t match_func, const void *match_data, const USHORT glyph_data[]) @@ -421,12 +371,21 @@ struct hb_apply_context_t match_glyph_data = glyph_data; } - inline bool has_no_chance (void) const { return unlikely (num_items && idx + num_items >= end); } + inline void reset (unsigned int start_index_, + unsigned int num_items_) + { + idx = start_index_; + num_items = num_items_; + end = c->buffer->len; + matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); + } + inline void reject (void) { num_items++; match_glyph_data--; } + inline bool next (void) { assert (num_items > 0); - while (!has_no_chance ()) + while (idx + num_items < end) { idx++; const hb_glyph_info_t &info = c->buffer->info[idx]; @@ -450,53 +409,10 @@ struct hb_apply_context_t } return false; } - - unsigned int idx; - protected: - hb_apply_context_t *c; - matcher_t matcher; - const USHORT *match_glyph_data; - - unsigned int num_items; - unsigned int end; - }; - - struct skipping_backward_iterator_t - { - inline skipping_backward_iterator_t (hb_apply_context_t *c_, - unsigned int start_index_, - unsigned int num_items_, - bool context_match = false) : - idx (start_index_), - c (c_), - match_glyph_data (NULL), - num_items (num_items_) - { - matcher.set_lookup_props (c->lookup_props); - /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ - matcher.set_ignore_zwnj (context_match || c->table_index == 1); - /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ - matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj); - if (!context_match) - matcher.set_mask (c->lookup_mask); - matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); - } - inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); } - inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); } - inline void set_match_func (matcher_t::match_func_t match_func, - const void *match_data, - const USHORT glyph_data[]) - { - matcher.set_match_func (match_func, match_data); - match_glyph_data = glyph_data; - } - - inline bool has_no_chance (void) const { return unlikely (idx < num_items); } - inline void reject (void) { num_items++; } inline bool prev (void) { assert (num_items > 0); - while (!has_no_chance ()) + while (idx >= num_items) { idx--; const hb_glyph_info_t &info = c->buffer->out_info[idx]; @@ -528,8 +444,75 @@ struct hb_apply_context_t const USHORT *match_glyph_data; unsigned int num_items; + unsigned int end; }; + + inline const char *get_name (void) { return "APPLY"; } + static const unsigned int max_debug_depth = HB_DEBUG_APPLY; + typedef bool return_t; + typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index); + template <typename T, typename F> + inline bool may_dispatch (const T *obj, const F *format) { return true; } + template <typename T> + inline return_t dispatch (const T &obj) { return obj.apply (this); } + static return_t default_return_value (void) { return false; } + bool stop_sublookup_iteration (return_t r) const { return r; } + return_t recurse (unsigned int lookup_index) + { + if (unlikely (nesting_level_left == 0 || !recurse_func)) + return default_return_value (); + + nesting_level_left--; + bool ret = recurse_func (this, lookup_index); + nesting_level_left++; + return ret; + } + + unsigned int table_index; /* GSUB/GPOS */ + hb_font_t *font; + hb_face_t *face; + hb_buffer_t *buffer; + hb_direction_t direction; + hb_mask_t lookup_mask; + bool auto_zwj; + recurse_func_t recurse_func; + unsigned int nesting_level_left; + unsigned int lookup_props; + const GDEF &gdef; + bool has_glyph_classes; + skipping_iterator_t iter_input, iter_context; + unsigned int debug_depth; + + + hb_apply_context_t (unsigned int table_index_, + hb_font_t *font_, + hb_buffer_t *buffer_) : + table_index (table_index_), + font (font_), face (font->face), buffer (buffer_), + direction (buffer_->props.direction), + lookup_mask (1), + auto_zwj (true), + recurse_func (NULL), + nesting_level_left (MAX_NESTING_LEVEL), + lookup_props (0), + gdef (*hb_ot_layout_from_face (face)->gdef), + has_glyph_classes (gdef.has_glyph_classes ()), + iter_input (), + iter_context (), + debug_depth (0) {} + + inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; } + inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; } + inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } + inline void set_lookup (const Lookup &l) { set_lookup_props (l.get_props ()); } + inline void set_lookup_props (unsigned int lookup_props_) + { + lookup_props = lookup_props_; + iter_input.init (this, false); + iter_context.init (this, true); + } + inline bool match_properties_mark (hb_codepoint_t glyph, unsigned int glyph_props, @@ -741,9 +724,9 @@ static inline bool match_input (hb_apply_context_t *c, hb_buffer_t *buffer = c->buffer; - hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, count - 1); + hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + skippy_iter.reset (buffer->idx, count - 1); skippy_iter.set_match_func (match_func, match_data, input); - if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); /* * This is perhaps the trickiest part of OpenType... Remarks: @@ -910,9 +893,9 @@ static inline bool match_backtrack (hb_apply_context_t *c, { TRACE_APPLY (NULL); - hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->backtrack_len (), count, true); + hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; + skippy_iter.reset (c->buffer->backtrack_len (), count); skippy_iter.set_match_func (match_func, match_data, backtrack); - if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); for (unsigned int i = 0; i < count; i++) if (!skippy_iter.prev ()) @@ -930,9 +913,9 @@ static inline bool match_lookahead (hb_apply_context_t *c, { TRACE_APPLY (NULL); - hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx + offset - 1, count, true); + hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; + skippy_iter.reset (c->buffer->idx + offset - 1, count); skippy_iter.set_match_func (match_func, match_data, lookahead); - if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); for (unsigned int i = 0; i < count; i++) if (!skippy_iter.next ()) @@ -945,7 +928,8 @@ static inline bool match_lookahead (hb_apply_context_t *c, struct LookupRecord { - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -1168,7 +1152,8 @@ struct Rule } public: - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return inputCount.sanitize (c) && lookupCount.sanitize (c) @@ -1232,7 +1217,8 @@ struct RuleSet return TRACE_RETURN (false); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (rule.sanitize (c, this)); } @@ -1314,7 +1300,8 @@ struct ContextFormat1 return TRACE_RETURN (rule_set.apply (c, lookup_context)); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); } @@ -1406,7 +1393,8 @@ struct ContextFormat2 return TRACE_RETURN (rule_set.apply (c, lookup_context)); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this)); } @@ -1494,7 +1482,8 @@ struct ContextFormat3 return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (!c->check_struct (this)) return TRACE_RETURN (false); unsigned int count = glyphCount; @@ -1502,7 +1491,7 @@ struct ContextFormat3 if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return TRACE_RETURN (false); for (unsigned int i = 0; i < count; i++) if (!coverageZ[i].sanitize (c, this)) return TRACE_RETURN (false); - LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count); + const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count); return TRACE_RETURN (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount)); } @@ -1526,6 +1515,7 @@ struct Context inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); switch (u.format) { case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 2: return TRACE_RETURN (c->dispatch (u.format2)); @@ -1534,17 +1524,6 @@ struct Context } } - inline bool sanitize (hb_sanitize_context_t *c) { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - case 2: return TRACE_RETURN (u.format2.sanitize (c)); - case 3: return TRACE_RETURN (u.format3.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -1726,14 +1705,15 @@ struct ChainRule lookup.array, lookup_context)); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (!backtrack.sanitize (c)) return TRACE_RETURN (false); - HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); + const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); if (!input.sanitize (c)) return TRACE_RETURN (false); - ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); + const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); if (!lookahead.sanitize (c)) return TRACE_RETURN (false); - ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); + const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); return TRACE_RETURN (lookup.sanitize (c)); } @@ -1795,7 +1775,8 @@ struct ChainRuleSet return TRACE_RETURN (false); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (rule.sanitize (c, this)); } @@ -1874,7 +1855,8 @@ struct ChainContextFormat1 return TRACE_RETURN (rule_set.apply (c, lookup_context)); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); } @@ -1984,7 +1966,8 @@ struct ChainContextFormat2 return TRACE_RETURN (rule_set.apply (c, lookup_context)); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.sanitize (c, this) && inputClassDef.sanitize (c, this) && lookaheadClassDef.sanitize (c, this) && @@ -2105,15 +2088,16 @@ struct ChainContextFormat3 lookup.len, lookup.array, lookup_context)); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false); - OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); + const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); if (!input.sanitize (c, this)) return TRACE_RETURN (false); if (!input.len) return TRACE_RETURN (false); /* To be consistent with Context. */ - OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); + const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false); - ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); + const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); return TRACE_RETURN (lookup.sanitize (c)); } @@ -2144,6 +2128,7 @@ struct ChainContext inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); switch (u.format) { case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 2: return TRACE_RETURN (c->dispatch (u.format2)); @@ -2152,17 +2137,6 @@ struct ChainContext } } - inline bool sanitize (hb_sanitize_context_t *c) { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - case 2: return TRACE_RETURN (u.format2.sanitize (c)); - case 3: return TRACE_RETURN (u.format3.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -2173,14 +2147,32 @@ struct ChainContext }; +template <typename T> struct ExtensionFormat1 { inline unsigned int get_type (void) const { return extensionLookupType; } - inline unsigned int get_offset (void) const { return extensionOffset; } - inline bool sanitize (hb_sanitize_context_t *c) { + template <typename X> + inline const X& get_subtable (void) const + { + unsigned int offset = extensionOffset; + if (unlikely (!offset)) return Null(typename T::LookupSubTable); + return StructAtOffset<typename T::LookupSubTable> (this, offset); + } + + template <typename context_t> + inline typename context_t::return_t dispatch (context_t *c) const + { + TRACE_DISPATCH (this, format); + if (unlikely (!c->may_dispatch (this, this))) TRACE_RETURN (c->default_return_value ()); + return get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ()); + } + + /* This is called from may_dispatch() above with hb_sanitize_context_t. */ + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return TRACE_RETURN (c->check_struct (this) && extensionOffset != 0); } protected: @@ -2204,49 +2196,30 @@ struct Extension default:return 0; } } - inline unsigned int get_offset (void) const - { - switch (u.format) { - case 1: return u.format1.get_offset (); - default:return 0; - } - } - template <typename X> inline const X& get_subtable (void) const { - unsigned int offset = get_offset (); - if (unlikely (!offset)) return Null(typename T::LookupSubTable); - return StructAtOffset<typename T::LookupSubTable> (this, offset); + switch (u.format) { + case 1: return u.format1.template get_subtable<typename T::LookupSubTable> (); + default:return Null(typename T::LookupSubTable); + } } template <typename context_t> inline typename context_t::return_t dispatch (context_t *c) const { - return get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ()); - } - - inline bool sanitize_self (hb_sanitize_context_t *c) { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); + TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); + case 1: return TRACE_RETURN (u.format1.dispatch (c)); + default:return TRACE_RETURN (c->default_return_value ()); } } - inline bool sanitize (hb_sanitize_context_t *c) { - TRACE_SANITIZE (this); - if (!sanitize_self (c)) return TRACE_RETURN (false); - unsigned int offset = get_offset (); - if (unlikely (!offset)) return TRACE_RETURN (true); - return TRACE_RETURN (StructAtOffset<typename T::LookupSubTable> (this, offset).sanitize (c, get_type ())); - } - protected: union { USHORT format; /* Format identifier */ - ExtensionFormat1 format1; + ExtensionFormat1<T> format1; } u; }; @@ -2291,7 +2264,8 @@ struct GSUBGPOS inline const Lookup& get_lookup (unsigned int i) const { return (this+lookupList)[i]; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) && scriptList.sanitize (c, this) && diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh index 67a6df5b42..739dfd9106 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh @@ -54,7 +54,8 @@ typedef OffsetListOf<PosLookup> JstfMax; struct JstfPriority { - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && shrinkageEnableGSUB.sanitize (c, this) && @@ -123,7 +124,8 @@ struct JstfPriority struct JstfLangSys : OffsetListOf<JstfPriority> { inline bool sanitize (hb_sanitize_context_t *c, - const Record<JstfLangSys>::sanitize_closure_t * = NULL) { + const Record<JstfLangSys>::sanitize_closure_t * = NULL) const + { TRACE_SANITIZE (this); return TRACE_RETURN (OffsetListOf<JstfPriority>::sanitize (c)); } @@ -163,7 +165,8 @@ struct JstfScript inline const JstfLangSys& get_default_lang_sys (void) const { return this+defaultLangSys; } inline bool sanitize (hb_sanitize_context_t *c, - const Record<JstfScript>::sanitize_closure_t * = NULL) { + const Record<JstfScript>::sanitize_closure_t * = NULL) const + { TRACE_SANITIZE (this); return TRACE_RETURN (extenderGlyphs.sanitize (c, this) && defaultLangSys.sanitize (c, this) && @@ -206,7 +209,8 @@ struct JSTF inline bool find_script_index (hb_tag_t tag, unsigned int *index) const { return scriptList.find_index (tag, index); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) && scriptList.sanitize (c, this)); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh index 3f7c858d1c..47fecd216d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh @@ -130,6 +130,11 @@ struct hb_ot_layout_lookup_accelerator_t { } + inline bool may_have (hb_codepoint_t g) const { + return digest.may_have (g); + } + + private: hb_set_digest_t digest; }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc index 602b94ecd6..b1e69e89f4 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc @@ -699,7 +699,7 @@ hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face, const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index); - return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_index].digest); + return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_index]); } void @@ -829,26 +829,83 @@ struct GPOSProxy }; -template <typename Lookup> -static inline bool apply_once (OT::hb_apply_context_t *c, - const Lookup &lookup) +template <typename Obj> +static inline bool +apply_forward (OT::hb_apply_context_t *c, + const Obj &obj, + const hb_ot_layout_lookup_accelerator_t &accel) { - if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) - return false; - return lookup.dispatch (c); + bool ret = false; + hb_buffer_t *buffer = c->buffer; + while (buffer->idx < buffer->len) + { + if (accel.may_have (buffer->cur().codepoint) && + (buffer->cur().mask & c->lookup_mask) && + c->check_glyph_property (&buffer->cur(), c->lookup_props) && + obj.apply (c)) + ret = true; + else + buffer->next_glyph (); + } + return ret; } -template <typename Proxy> +template <typename Obj> static inline bool +apply_backward (OT::hb_apply_context_t *c, + const Obj &obj, + const hb_ot_layout_lookup_accelerator_t &accel) +{ + bool ret = false; + hb_buffer_t *buffer = c->buffer; + do + { + if (accel.may_have (buffer->cur().codepoint) && + (buffer->cur().mask & c->lookup_mask) && + c->check_glyph_property (&buffer->cur(), c->lookup_props) && + obj.apply (c)) + ret = true; + /* The reverse lookup doesn't "advance" cursor (for good reason). */ + buffer->idx--; + + } + while ((int) buffer->idx >= 0); + return ret; +} + +struct hb_apply_forward_context_t +{ + inline const char *get_name (void) { return "APPLY_FORWARD"; } + static const unsigned int max_debug_depth = HB_DEBUG_APPLY; + typedef bool return_t; + template <typename T, typename F> + inline bool may_dispatch (const T *obj, const F *format) { return true; } + template <typename T> + inline return_t dispatch (const T &obj) { return apply_forward (c, obj, accel); } + static return_t default_return_value (void) { return false; } + bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return true; } + + hb_apply_forward_context_t (OT::hb_apply_context_t *c_, + const hb_ot_layout_lookup_accelerator_t &accel_) : + c (c_), + accel (accel_), + debug_depth (0) {} + + OT::hb_apply_context_t *c; + const hb_ot_layout_lookup_accelerator_t &accel; + unsigned int debug_depth; +}; + +template <typename Proxy> +static inline void apply_string (OT::hb_apply_context_t *c, const typename Proxy::Lookup &lookup, const hb_ot_layout_lookup_accelerator_t &accel) { - bool ret = false; hb_buffer_t *buffer = c->buffer; if (unlikely (!buffer->len || !c->lookup_mask)) - return false; + return; c->set_lookup (lookup); @@ -859,21 +916,20 @@ apply_string (OT::hb_apply_context_t *c, buffer->clear_output (); buffer->idx = 0; - while (buffer->idx < buffer->len) + bool ret; + if (lookup.get_subtable_count () == 1) { - if (accel.digest.may_have (buffer->cur().codepoint) && - (buffer->cur().mask & c->lookup_mask) && - apply_once (c, lookup)) - ret = true; - else - buffer->next_glyph (); + hb_apply_forward_context_t c_forward (c, accel); + ret = lookup.dispatch (&c_forward); } + else + ret = apply_forward (c, lookup, accel); if (ret) { if (!Proxy::inplace) buffer->swap_buffers (); else - assert (!buffer->has_separate_output ()); + assert (!buffer->has_separate_output ()); } } else @@ -882,20 +938,9 @@ apply_string (OT::hb_apply_context_t *c, if (Proxy::table_index == 0) buffer->remove_output (); buffer->idx = buffer->len - 1; - do - { - if (accel.digest.may_have (buffer->cur().codepoint) && - (buffer->cur().mask & c->lookup_mask) && - apply_once (c, lookup)) - ret = true; - /* The reverse lookup doesn't "advance" cursor (for good reason). */ - buffer->idx--; - } - while ((int) buffer->idx >= 0); + apply_backward (c, lookup, accel); } - - return ret; } template <typename Proxy> diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh index b1f832852d..0d9a0fa1d8 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh @@ -43,11 +43,13 @@ struct maxp { static const hb_tag_t tableTag = HB_OT_TAG_maxp; - inline unsigned int get_num_glyphs (void) const { + inline unsigned int get_num_glyphs (void) const + { return numGlyphs; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1 || (version.major == 0 && version.minor == 0x5000u))); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh index 31d9fac7e2..21450c6138 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh @@ -56,7 +56,8 @@ struct NameRecord return 0; } - inline bool sanitize (hb_sanitize_context_t *c, void *base) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { TRACE_SANITIZE (this); /* We can check from base all the way up to the end of string... */ return TRACE_RETURN (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset)); @@ -101,7 +102,7 @@ struct name inline unsigned int get_size (void) const { return min_size + count * nameRecord[0].min_size; } - inline bool sanitize_records (hb_sanitize_context_t *c) { + inline bool sanitize_records (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); char *string_pool = (char *) this + stringOffset; unsigned int _count = count; @@ -110,7 +111,8 @@ struct name return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && likely (format == 0 || format == 1) && diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc index 80d7da82f3..53274b502a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc @@ -441,13 +441,15 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, OT::hb_apply_context_t c (1, font, buffer); c.set_lookup_mask (plan->kern_mask); c.set_lookup_props (OT::LookupFlag::IgnoreMarks); + OT::hb_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input; + skippy_iter.init (&c); unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; hb_glyph_position_t *pos = buffer->pos; for (unsigned int idx = 0; idx < count;) { - OT::hb_apply_context_t::skipping_forward_iterator_t skippy_iter (&c, idx, 1); + skippy_iter.reset (idx, 1); if (!skippy_iter.next ()) { idx++; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-private.hh index cfe77f1606..06b24a80f8 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-private.hh @@ -573,6 +573,30 @@ _hb_debug (unsigned int level, #define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT)) #define DEBUG_ENABLED(WHAT) (DEBUG_LEVEL_ENABLED (WHAT, 0)) +static inline void +_hb_print_func (const char *func) +{ + if (func) + { + unsigned int func_len = strlen (func); + /* Skip "static" */ + if (0 == strncmp (func, "static ", 7)) + func += 7; + /* Skip "typename" */ + if (0 == strncmp (func, "typename ", 9)) + func += 9; + /* Skip return type */ + const char *space = strchr (func, ' '); + if (space) + func = space + 1; + /* Skip parameter list */ + const char *paren = strchr (func, '('); + if (paren) + func_len = paren - func; + fprintf (stderr, "%.*s", func_len, func); + } +} + template <int max_level> static inline void _hb_debug_msg_va (const char *what, const void *obj, @@ -618,27 +642,13 @@ _hb_debug_msg_va (const char *what, } else fprintf (stderr, " " VRBAR LBAR); - if (func) - { - unsigned int func_len = strlen (func); -#ifndef HB_DEBUG_VERBOSE - /* Skip "typename" */ - if (0 == strncmp (func, "typename ", 9)) - func += 9; - /* Skip return type */ - const char *space = strchr (func, ' '); - if (space) - func = space + 1; - /* Skip parameter list */ - const char *paren = strchr (func, '('); - if (paren) - func_len = paren - func; -#endif - fprintf (stderr, "%.*s: ", func_len, func); - } + _hb_print_func (func); if (message) + { + fprintf (stderr, ": "); vfprintf (stderr, message, ap); + } fprintf (stderr, "\n"); } @@ -810,7 +820,7 @@ hb_in_range (T u, T lo, T hi) /* The sizeof() is here to force template instantiation. * I'm sure there are better ways to do this but can't think of * one right now. Declaring a variable won't work as HB_UNUSED - * is unsable on some platforms and unused types are less likely + * is unusable on some platforms and unused types are less likely * to generate a warning than unused variables. */ ASSERT_STATIC (sizeof (hb_assert_unsigned_t<T>) >= 0); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh index 59e8f4559f..acba4e946b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh @@ -145,6 +145,8 @@ typedef hb_set_digest_combiner_t struct hb_set_t { + friend struct hb_frozen_set_t; + hb_object_header_t header; ASSERT_POD (); bool in_error; @@ -326,7 +328,7 @@ struct hb_set_t static const hb_codepoint_t INVALID = HB_SET_VALUE_INVALID; elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; } - elt_t elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; } + elt_t const &elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; } elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); } elt_t elts[ELTS]; /* XXX 8kb */ @@ -335,6 +337,59 @@ struct hb_set_t ASSERT_STATIC (sizeof (elt_t) * 8 * ELTS > MAX_G); }; +struct hb_frozen_set_t +{ + static const unsigned int SHIFT = hb_set_t::SHIFT; + static const unsigned int BITS = hb_set_t::BITS; + static const unsigned int MASK = hb_set_t::MASK; + typedef hb_set_t::elt_t elt_t; + + inline void init (const hb_set_t &set) + { + start = count = 0; + elts = NULL; + + unsigned int max = set.get_max (); + if (max == set.INVALID) + return; + unsigned int min = set.get_min (); + const elt_t &min_elt = set.elt (min); + const elt_t &max_elt = set.elt (max); + + start = min & ~MASK; + count = max - start + 1; + unsigned int num_elts = (count + BITS - 1) / BITS; + unsigned int elts_size = num_elts * sizeof (elt_t); + elts = (elt_t *) malloc (elts_size); + if (unlikely (!elts)) + { + start = count = 0; + return; + } + memcpy (elts, &min_elt, elts_size); + } + + inline void fini (void) + { + if (elts) + free (elts); + } + + inline bool has (hb_codepoint_t g) const + { + /* hb_codepoint_t is unsigned. */ + g -= start; + if (unlikely (g > count)) return false; + return !!(elt (g) & mask (g)); + } + + elt_t const &elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; } + elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); } + + private: + hb_codepoint_t start, count; + elt_t *elts; +}; #endif /* HB_SET_PRIVATE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h b/src/3rdparty/harfbuzz-ng/src/hb-version.h index b9f8a057c9..eacdc598d9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-version.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-version.h @@ -38,9 +38,9 @@ HB_BEGIN_DECLS #define HB_VERSION_MAJOR 0 #define HB_VERSION_MINOR 9 -#define HB_VERSION_MICRO 38 +#define HB_VERSION_MICRO 39 -#define HB_VERSION_STRING "0.9.38" +#define HB_VERSION_STRING "0.9.39" #define HB_VERSION_ATLEAST(major,minor,micro) \ ((major)*10000+(minor)*100+(micro) <= \ diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-thai.c b/src/3rdparty/harfbuzz/src/harfbuzz-thai.c index b79e0b6cb7..7438d5994c 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-thai.c +++ b/src/3rdparty/harfbuzz/src/harfbuzz-thai.c @@ -68,7 +68,7 @@ static int init_libthai() { return 0; } -static void to_tis620(const HB_UChar16 *string, hb_uint32 len, const char *cstr) +static void to_tis620(const HB_UChar16 *string, hb_uint32 len, char *cstr) { hb_uint32 i; unsigned char *result = (unsigned char *)cstr; @@ -183,7 +183,7 @@ static int thai_contain_glyphs (HB_ShaperItem *shaper_item, const int glyph_map[ for (c = 0; c < 0x80; c++) { if ( glyph_map[c] ) { - if ( !shaper_item->font->klass->canRender (shaper_item->font, (HB_UChar16 *) &glyph_map[c], 1) ) + if ( !shaper_item->font->klass->canRender (shaper_item->font, (const HB_UChar16 *) &glyph_map[c], 1) ) return 0; } } diff --git a/src/3rdparty/harfbuzzng.pri b/src/3rdparty/harfbuzz_dependency.pri index 74433688f6..74433688f6 100644 --- a/src/3rdparty/harfbuzzng.pri +++ b/src/3rdparty/harfbuzz_dependency.pri 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 93d7baabdb..c7355c1530 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -65,6 +65,7 @@ import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; +import android.widget.LinearLayout; import java.io.BufferedReader; import java.io.DataOutputStream; @@ -788,7 +789,29 @@ public class QtActivityDelegate 0, 0, metrics.xdpi, metrics.ydpi, metrics.scaledDensity); } + + ViewGroup layout = null; m_layout = new QtLayout(m_activity); + if (Build.VERSION.SDK_INT >= 14) { + try { + ActivityInfo activityInfo = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(), + PackageManager.GET_META_DATA); + if (activityInfo.metaData == null + || !activityInfo.metaData.containsKey("android.app.allow_overlapping_system_ui") + || !activityInfo.metaData.getBoolean("android.app.allow_overlapping_system_ui")) { + layout = new LinearLayout(m_activity); + layout.setFitsSystemWindows(true); + layout.addView(m_layout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (layout == null) + layout = m_layout; + m_editText = new QtEditText(m_activity, this); m_imm = (InputMethodManager)m_activity.getSystemService(Context.INPUT_METHOD_SERVICE); m_surfaces = new HashMap<Integer, QtSurface>(); @@ -811,7 +834,7 @@ public class QtActivityDelegate Log.w("Qt A11y", "Unknown exception: " + e.toString()); } - m_activity.setContentView(m_layout, + m_activity.setContentView(layout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); 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 8e35840a20..bed9d69782 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -279,12 +279,14 @@ public class QtNative if (action == MotionEvent.ACTION_MOVE) { int hsz = event.getHistorySize(); if (hsz > 0) { - if (event.getX(index) != event.getHistoricalX(index, hsz-1) - || event.getY(index) != event.getHistoricalY(index, hsz-1)) { - return 1; - } else { - return 2; + float x = event.getX(index); + float y = event.getY(index); + for (int h = 0; h < hsz; ++h) { + if ( event.getHistoricalX(index, h) != x || + event.getHistoricalY(index, h) != y ) + return 1; } + return 2; } return 1; } diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml index 60c612976f..779612cdaf 100644 --- a/src/android/templates/AndroidManifest.xml +++ b/src/android/templates/AndroidManifest.xml @@ -44,6 +44,10 @@ signal is sent! --> <meta-data android:name="android.app.background_running" android:value="false"/> <!-- Background running --> + + <!-- Show translucent UI on top of Qt's surface when system theme mandates it --> + <meta-data android:name="android.app.allow_overlapping_system_ui" android:value="false"/> + <!-- Show translucent UI on top of Qt's surface when system theme mandates it --> </activity> </application> <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="14"/> diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake index 95102be108..a94caf0d25 100644 --- a/src/corelib/Qt5CoreMacros.cmake +++ b/src/corelib/Qt5CoreMacros.cmake @@ -269,7 +269,7 @@ function(QT5_ADD_RESOURCES outfiles ) set(rcc_files ${_RCC_UNPARSED_ARGUMENTS}) set(rcc_options ${_RCC_OPTIONS}) - if(${rcc_options} MATCHES "-binary") + if("${rcc_options}" MATCHES "-binary") message(WARNING "Use qt5_add_binary_resources for binary option") endif() diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf index f3aff83a8b..df1ee4afea 100644 --- a/src/corelib/doc/qtcore.qdocconf +++ b/src/corelib/doc/qtcore.qdocconf @@ -36,7 +36,8 @@ exampledirs += \ ../ \ snippets \ ../../../examples/corelib \ - ../../../examples/network/dnslookup + ../../../examples/network/dnslookup \ + ../../../examples/widgets/tools imagedirs += images diff --git a/src/corelib/doc/src/datastreamformat.qdoc b/src/corelib/doc/src/datastreamformat.qdoc index c76cc1a95e..8ebc64ca85 100644 --- a/src/corelib/doc/src/datastreamformat.qdoc +++ b/src/corelib/doc/src/datastreamformat.qdoc @@ -129,7 +129,9 @@ \li \list \li Date (QDate) \li Time (QTime) - \li The \l{Qt::TimeSpec}{time spec} (quint8) + \li The \l{Qt::TimeSpec}{time spec} + offsetFromUtc (qint32) if Qt::TimeSpec is offsetFromUtc + TimeZone(QTimeZone) if Qt::TimeSpec is TimeZone \endlist \row \li QEasingCurve \li \list @@ -145,11 +147,19 @@ \row \li QFont \li \list \li The family (QString) - \li The point size (qint16) + \li The style name (QString) + \li The point size (double) + \li The pixel size (qint32) \li The style hint (quint8) + \li The style strategy (quint16) \li The char set (quint8) \li The weight (quint8) \li The font bits (quint8) + \li The font stretch (quint16) + \li The extended font bits (quint8) + \li The letter spacing (double) + \li The word spacing (double) + \li The hinting preference (quint8) \endlist \row \li QHash<Key, T> \li \list diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 0ca67df1e2..1774378c06 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -1164,7 +1164,6 @@ const bool valueOfExpression = Expr;\ Q_ASSERT_X(valueOfExpression, "Q_ASSUME()", "Assumption in Q_ASSUME(\"" #Expr "\") was not correct");\ Q_ASSUME_IMPL(valueOfExpression);\ - Q_UNUSED(valueOfExpression); /* the value may not be used if Q_ASSERT_X and Q_ASSUME_IMPL are noop */\ } while (0) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 6aa3eb305b..c4e2f7609c 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -681,7 +681,7 @@ Q_CORE_EXPORT void qt_assert_x(const char *where, const char *what, const char * #if !defined(Q_ASSERT_X) # if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) -# define Q_ASSERT_X(cond, where, what) qt_noop() +# define Q_ASSERT_X(cond, where, what) do { } while ((false) && (cond)) # else # define Q_ASSERT_X(cond, where, what) ((!(cond)) ? qt_assert_x(where, what,__FILE__,__LINE__) : qt_noop()) # endif diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 322fc2f651..5db2e94602 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -63,12 +63,16 @@ extern void qDumpCPUFeatures(); // in qsimd.cpp struct QLibrarySettings { QLibrarySettings(); + void load(); + QScopedPointer<QSettings> settings; #ifdef QT_BUILD_QMAKE bool haveDevicePaths; bool haveEffectiveSourcePaths; bool haveEffectivePaths; bool havePaths; +#else + bool reloadOnQAppAvailable; #endif }; Q_GLOBAL_STATIC(QLibrarySettings, qt_library_settings) @@ -93,16 +97,31 @@ public: static QSettings *configuration() { QLibrarySettings *ls = qt_library_settings(); - return ls ? ls->settings.data() : 0; + if (ls) { +#ifndef QT_BUILD_QMAKE + if (ls->reloadOnQAppAvailable && QCoreApplication::instance() != 0) + ls->load(); +#endif + return ls->settings.data(); + } else { + return 0; + } } }; static const char platformsSection[] = "Platforms"; QLibrarySettings::QLibrarySettings() - : settings(QLibraryInfoPrivate::findConfiguration()) { + load(); +} + +void QLibrarySettings::load() +{ + // If we get any settings here, those won't change when the application shows up. + settings.reset(QLibraryInfoPrivate::findConfiguration()); #ifndef QT_BUILD_QMAKE + reloadOnQAppAvailable = (settings.data() == 0 && QCoreApplication::instance() == 0); bool haveDevicePaths; bool haveEffectivePaths; bool havePaths; @@ -139,33 +158,35 @@ QLibrarySettings::QLibrarySettings() QSettings *QLibraryInfoPrivate::findConfiguration() { QString qtconfig = QStringLiteral(":/qt/etc/qt.conf"); + if (QFile::exists(qtconfig)) + return new QSettings(qtconfig, QSettings::IniFormat); #ifdef QT_BUILD_QMAKE - if(!QFile::exists(qtconfig)) - qtconfig = qmake_libraryInfoFile(); + qtconfig = qmake_libraryInfoFile(); + if (QFile::exists(qtconfig)) + return new QSettings(qtconfig, QSettings::IniFormat); #else - if (!QFile::exists(qtconfig) && QCoreApplication::instance()) { #ifdef Q_OS_MAC - CFBundleRef bundleRef = CFBundleGetMainBundle(); - if (bundleRef) { - QCFType<CFURLRef> urlRef = CFBundleCopyResourceURL(bundleRef, - QCFString(QLatin1String("qt.conf")), - 0, - 0); - if (urlRef) { - QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle); - qtconfig = QDir::cleanPath(path); - } + CFBundleRef bundleRef = CFBundleGetMainBundle(); + if (bundleRef) { + QCFType<CFURLRef> urlRef = CFBundleCopyResourceURL(bundleRef, + QCFString(QLatin1String("qt.conf")), + 0, + 0); + if (urlRef) { + QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle); + qtconfig = QDir::cleanPath(path); + if (QFile::exists(qtconfig)) + return new QSettings(qtconfig, QSettings::IniFormat); } - if (qtconfig.isEmpty()) + } #endif - { - QDir pwd(QCoreApplication::applicationDirPath()); - qtconfig = pwd.filePath(QLatin1String("qt.conf")); - } + if (QCoreApplication::instance()) { + QDir pwd(QCoreApplication::applicationDirPath()); + qtconfig = pwd.filePath(QLatin1String("qt.conf")); + if (QFile::exists(qtconfig)) + return new QSettings(qtconfig, QSettings::IniFormat); } #endif - if (QFile::exists(qtconfig)) - return new QSettings(qtconfig, QSettings::IniFormat); return 0; //no luck } diff --git a/src/corelib/io/forkfd_qt.cpp b/src/corelib/io/forkfd_qt.cpp index 56a39f8df0..6704ec6f2a 100644 --- a/src/corelib/io/forkfd_qt.cpp +++ b/src/corelib/io/forkfd_qt.cpp @@ -36,10 +36,17 @@ # define _POSIX_C_SOURCE 200809L #endif #if !defined(_XOPEN_SOURCE) && !defined(__QNXNTO__) && !defined(ANDROID) -# define _XOPEN_SOURCE 500 +# define _XOPEN_SOURCE 700 #endif #include <QtCore/qatomic.h> +#include "qprocess_p.h" + +#ifdef QPROCESS_USE_SPAWN +# define FORKFD_NO_FORKFD +#else +# define FORKFD_NO_SPAWNFD +#endif #if defined(QT_NO_DEBUG) && !defined(NDEBUG) # define NDEBUG diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index ea7e7b2731..7eb917c71f 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -586,7 +586,7 @@ qint64 QIODevice::pos() const { Q_D(const QIODevice); #if defined QIODEVICE_DEBUG - printf("%p QIODevice::pos() == %d\n", this, int(d->pos)); + printf("%p QIODevice::pos() == %lld\n", this, d->pos); #endif return d->pos; } @@ -629,31 +629,30 @@ bool QIODevice::seek(qint64 pos) return false; } if (pos < 0) { - qWarning("QIODevice::seek: Invalid pos: %d", int(pos)); + qWarning("QIODevice::seek: Invalid pos: %lld", pos); return false; } #if defined QIODEVICE_DEBUG - printf("%p QIODevice::seek(%d), before: d->pos = %d, d->buffer.size() = %d\n", - this, int(pos), int(d->pos), d->buffer.size()); + printf("%p QIODevice::seek(%lld), before: d->pos = %lld, d->buffer.size() = %lld\n", + this, pos, d->pos, d->buffer.size()); #endif qint64 offset = pos - d->pos; d->pos = pos; d->devicePos = pos; - if (offset < 0 - || offset >= qint64(d->buffer.size())) + if (offset < 0 || offset >= d->buffer.size()) // When seeking backwards, an operation that is only allowed for // random-access devices, the buffer is cleared. The next read // operation will then refill the buffer. We can optimize this, if we // find that seeking backwards becomes a significant performance hit. d->buffer.clear(); else if (!d->buffer.isEmpty()) - d->buffer.skip(int(offset)); + d->buffer.skip(offset); #if defined QIODEVICE_DEBUG - printf("%p \tafter: d->pos == %d, d->buffer.size() == %d\n", this, int(d->pos), + printf("%p \tafter: d->pos == %lld, d->buffer.size() == %lld\n", this, d->pos, d->buffer.size()); #endif return true; @@ -675,8 +674,9 @@ bool QIODevice::atEnd() const { Q_D(const QIODevice); #if defined QIODEVICE_DEBUG - printf("%p QIODevice::atEnd() returns %s, d->openMode == %d, d->pos == %d\n", this, (d->openMode == NotOpen || d->pos == size()) ? "true" : "false", - int(d->openMode), int(d->pos)); + printf("%p QIODevice::atEnd() returns %s, d->openMode == %d, d->pos == %lld\n", this, + (d->openMode == NotOpen || d->pos == size()) ? "true" : "false", int(d->openMode), + d->pos); #endif return d->openMode == NotOpen || (d->buffer.isEmpty() && bytesAvailable() == 0); } @@ -749,8 +749,8 @@ qint64 QIODevice::read(char *data, qint64 maxSize) Q_D(QIODevice); #if defined QIODEVICE_DEBUG - printf("%p QIODevice::read(%p, %d), d->pos = %d, d->buffer.size() = %d\n", - this, data, int(maxSize), int(d->pos), int(d->buffer.size())); + printf("%p QIODevice::read(%p, %lld), d->pos = %lld, d->buffer.size() = %lld\n", + this, data, maxSize, d->pos, d->buffer.size()); #endif const bool sequential = d->isSequential(); @@ -791,8 +791,8 @@ qint64 QIODevice::read(char *data, qint64 maxSize) data += bufferReadChunkSize; maxSize -= bufferReadChunkSize; #if defined QIODEVICE_DEBUG - printf("%p \treading %d bytes from buffer into position %d\n", this, - bufferReadChunkSize, int(readSoFar) - bufferReadChunkSize); + printf("%p \treading %lld bytes from buffer into position %lld\n", this, + bufferReadChunkSize, readSoFar - bufferReadChunkSize); #endif } else { if (d->firstRead) { @@ -813,8 +813,8 @@ qint64 QIODevice::read(char *data, qint64 maxSize) readFromDevice = readData(data, maxSize); deviceAtEof = (readFromDevice != maxSize); #if defined QIODEVICE_DEBUG - printf("%p \treading %d bytes from device (total %d)\n", this, - int(readFromDevice), int(readSoFar)); + printf("%p \treading %lld bytes from device (total %lld)\n", this, + readFromDevice, readSoFar); #endif if (readFromDevice > 0) { readSoFar += readFromDevice; @@ -826,17 +826,17 @@ qint64 QIODevice::read(char *data, qint64 maxSize) } } } else { - const int bytesToBuffer = QIODEVICE_BUFFERSIZE; + const qint64 bytesToBuffer = QIODEVICE_BUFFERSIZE; // Try to fill QIODevice buffer by single read readFromDevice = readData(d->buffer.reserve(bytesToBuffer), bytesToBuffer); deviceAtEof = (readFromDevice != bytesToBuffer); - d->buffer.chop(bytesToBuffer - qMax(0, int(readFromDevice))); + d->buffer.chop(bytesToBuffer - qMax(Q_INT64_C(0), readFromDevice)); if (readFromDevice > 0) { if (!sequential) d->devicePos += readFromDevice; #if defined QIODEVICE_DEBUG - printf("%p \treading %d from device into buffer\n", this, - int(readFromDevice)); + printf("%p \treading %lld from device into buffer\n", this, + readFromDevice); #endif continue; } @@ -884,8 +884,8 @@ qint64 QIODevice::read(char *data, qint64 maxSize) } #if defined QIODEVICE_DEBUG - printf("%p \treturning %d, d->pos == %d, d->buffer.size() == %d\n", this, - int(readSoFar), int(d->pos), d->buffer.size()); + printf("%p \treturning %lld, d->pos == %lld, d->buffer.size() == %lld\n", this, + readSoFar, d->pos, d->buffer.size()); debugBinaryString(data - readSoFar, readSoFar); #endif @@ -916,8 +916,8 @@ QByteArray QIODevice::read(qint64 maxSize) CHECK_MAXLEN(read, result); #if defined QIODEVICE_DEBUG - printf("%p QIODevice::read(%d), d->pos = %d, d->buffer.size() = %d\n", - this, int(maxSize), int(d->pos), int(d->buffer.size())); + printf("%p QIODevice::read(%lld), d->pos = %lld, d->buffer.size() = %lld\n", + this, maxSize, d->pos, d->buffer.size()); #else Q_UNUSED(d); #endif @@ -966,8 +966,8 @@ QByteArray QIODevice::readAll() { Q_D(QIODevice); #if defined QIODEVICE_DEBUG - printf("%p QIODevice::readAll(), d->pos = %d, d->buffer.size() = %d\n", - this, int(d->pos), int(d->buffer.size())); + printf("%p QIODevice::readAll(), d->pos = %lld, d->buffer.size() = %lld\n", + this, d->pos, d->buffer.size()); #endif QByteArray result; @@ -1054,8 +1054,8 @@ qint64 QIODevice::readLine(char *data, qint64 maxSize) } #if defined QIODEVICE_DEBUG - printf("%p QIODevice::readLine(%p, %d), d->pos = %d, d->buffer.size() = %d\n", - this, data, int(maxSize), int(d->pos), int(d->buffer.size())); + printf("%p QIODevice::readLine(%p, %lld), d->pos = %lld, d->buffer.size() = %lld\n", + this, data, maxSize, d->pos, d->buffer.size()); #endif // Leave room for a '\0' @@ -1071,8 +1071,8 @@ qint64 QIODevice::readLine(char *data, qint64 maxSize) if (!sequential) d->pos += readSoFar; #if defined QIODEVICE_DEBUG - printf("%p \tread from buffer: %d bytes, last character read: %hhx\n", this, - int(readSoFar), data[int(readSoFar) - 1]); + printf("%p \tread from buffer: %lld bytes, last character read: %hhx\n", this, + readSoFar, data[readSoFar - 1]); if (readSoFar) debugBinaryString(data, int(readSoFar)); #endif @@ -1094,8 +1094,8 @@ qint64 QIODevice::readLine(char *data, qint64 maxSize) d->baseReadLineDataCalled = false; qint64 readBytes = readLineData(data + readSoFar, maxSize - readSoFar); #if defined QIODEVICE_DEBUG - printf("%p \tread from readLineData: %d bytes, readSoFar = %d bytes\n", this, - int(readBytes), int(readSoFar)); + printf("%p \tread from readLineData: %lld bytes, readSoFar = %lld bytes\n", this, + readBytes, readSoFar); if (readBytes > 0) { debugBinaryString(data, int(readSoFar + readBytes)); } @@ -1122,8 +1122,8 @@ qint64 QIODevice::readLine(char *data, qint64 maxSize) } #if defined QIODEVICE_DEBUG - printf("%p \treturning %d, d->pos = %d, d->buffer.size() = %d, size() = %d\n", - this, int(readSoFar), int(d->pos), d->buffer.size(), int(size())); + printf("%p \treturning %lld, d->pos = %lld, d->buffer.size() = %lld, size() = %lld\n", + this, readSoFar, d->pos, d->buffer.size(), size()); debugBinaryString(data, int(readSoFar)); #endif return readSoFar; @@ -1147,8 +1147,8 @@ QByteArray QIODevice::readLine(qint64 maxSize) CHECK_MAXLEN(readLine, result); #if defined QIODEVICE_DEBUG - printf("%p QIODevice::readLine(%d), d->pos = %d, d->buffer.size() = %d\n", - this, int(maxSize), int(d->pos), int(d->buffer.size())); + printf("%p QIODevice::readLine(%lld), d->pos = %lld, d->buffer.size() = %lld\n", + this, maxSize, d->pos, d->buffer.size()); #else Q_UNUSED(d); #endif @@ -1220,8 +1220,8 @@ qint64 QIODevice::readLineData(char *data, qint64 maxSize) } #if defined QIODEVICE_DEBUG - printf("%p QIODevice::readLineData(%p, %d), d->pos = %d, d->buffer.size() = %d, returns %d\n", - this, data, int(maxSize), int(d->pos), int(d->buffer.size()), int(readSoFar)); + printf("%p QIODevice::readLineData(%p, %lld), d->pos = %lld, d->buffer.size() = %lld, " + "returns %lld\n", this, data, maxSize, d->pos, d->buffer.size(), readSoFar); #endif if (lastReadReturn != 1 && readSoFar == 0) return isSequential() ? lastReadReturn : -1; diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp index a993fd6ea4..77a3d0a2b8 100644 --- a/src/corelib/json/qjsonarray.cpp +++ b/src/corelib/json/qjsonarray.cpp @@ -47,6 +47,7 @@ QT_BEGIN_NAMESPACE \class QJsonArray \inmodule QtCore \ingroup json + \ingroup shared \reentrant \since 5.0 diff --git a/src/corelib/json/qjsondocument.cpp b/src/corelib/json/qjsondocument.cpp index 7014c146d5..f5bad32233 100644 --- a/src/corelib/json/qjsondocument.cpp +++ b/src/corelib/json/qjsondocument.cpp @@ -47,6 +47,7 @@ QT_BEGIN_NAMESPACE /*! \class QJsonDocument \inmodule QtCore \ingroup json + \ingroup shared \reentrant \since 5.0 diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp index 22bad6f8a2..ae44cd9ff9 100644 --- a/src/corelib/json/qjsonobject.cpp +++ b/src/corelib/json/qjsonobject.cpp @@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE \class QJsonObject \inmodule QtCore \ingroup json + \ingroup shared \reentrant \since 5.0 diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp index 371a191d3f..0d62687388 100644 --- a/src/corelib/json/qjsonparser.cpp +++ b/src/corelib/json/qjsonparser.cpp @@ -77,6 +77,7 @@ QT_BEGIN_NAMESPACE \class QJsonParseError \inmodule QtCore \ingroup json + \ingroup shared \reentrant \since 5.0 diff --git a/src/corelib/json/qjsonparser_p.h b/src/corelib/json/qjsonparser_p.h index 98b23dc9c5..a395c0c92e 100644 --- a/src/corelib/json/qjsonparser_p.h +++ b/src/corelib/json/qjsonparser_p.h @@ -62,12 +62,14 @@ public: class ParsedObject { public: - ParsedObject(Parser *p, int pos) : parser(p), objectPosition(pos) {} + ParsedObject(Parser *p, int pos) : parser(p), objectPosition(pos) { + offsets.reserve(64); + } void insert(uint offset); Parser *parser; int objectPosition; - QVarLengthArray<uint, 64> offsets; + QVector<uint> offsets; inline QJsonPrivate::Entry *entryAt(int i) const { return reinterpret_cast<QJsonPrivate::Entry *>(parser->data + objectPosition + offsets[i]); diff --git a/src/corelib/json/qjsonvalue.cpp b/src/corelib/json/qjsonvalue.cpp index 4845d8c876..c8ddfbc2cc 100644 --- a/src/corelib/json/qjsonvalue.cpp +++ b/src/corelib/json/qjsonvalue.cpp @@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE \class QJsonValue \inmodule QtCore \ingroup json + \ingroup shared \reentrant \since 5.0 diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 0bde57c8b3..dbffa83cee 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -2420,16 +2420,27 @@ Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive)) Returns a list of paths that the application will search when dynamically loading libraries. + The return value of this function may change when a QCoreApplication + is created. It is not recommended to call it before creating a + QCoreApplication. The directory of the application executable (\b not + the working directory) is part of the list if it is known. In order + to make it known a QCoreApplication has to be constructed as it will + use \c {argv[0]} to find it. + Qt provides default library paths, but they can also be set using a \l{Using qt.conf}{qt.conf} file. Paths specified in this file - will override default values. + will override default values. Note that if the qt.conf file is in + the directory of the application executable, it may not be found + until a QCoreApplication is created. If it is not found when calling + this function, the default library paths will be used. - This list will include the installation directory for plugins if + The list will include the installation directory for plugins if it exists (the default installation directory for plugins is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was - installed). The directory of the application executable (NOT the - working directory) is always added, as well as the colon separated - entries of the \c QT_PLUGIN_PATH environment variable. + installed). The colon separated entries of the \c QT_PLUGIN_PATH + environment variable are always added. The plugin installation + directory (and its existence) may change when the directory of + the application executable becomes known. If you want to iterate over the list, you can use the \l foreach pseudo-keyword: diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 9ae6c779c0..f7a4abbf68 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -2536,7 +2536,7 @@ QModelIndex QVariant::toModelIndex() const \sa canConvert(), convert(), toModelIndex() */ -QModelIndex QVariant::toPersistentModelIndex() const +QPersistentModelIndex QVariant::toPersistentModelIndex() const { return qVariantToHelper<QPersistentModelIndex>(d, handlerManager); } diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index d9eca94391..58dfc3aab0 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -320,7 +320,7 @@ class Q_CORE_EXPORT QVariant QEasingCurve toEasingCurve() const; QUuid toUuid() const; QModelIndex toModelIndex() const; - QModelIndex toPersistentModelIndex() const; + QPersistentModelIndex toPersistentModelIndex() const; QJsonValue toJsonValue() const; QJsonObject toJsonObject() const; QJsonArray toJsonArray() const; diff --git a/src/corelib/plugin/qplugin.qdoc b/src/corelib/plugin/qplugin.qdoc index 81be1df518..94f5bc8a30 100644 --- a/src/corelib/plugin/qplugin.qdoc +++ b/src/corelib/plugin/qplugin.qdoc @@ -44,7 +44,7 @@ to the interface class called \a ClassName. The \a Identifier must be unique. For example: - \snippet code/doc_src_qplugin.cpp 0 + \snippet plugandpaint/interfaces.h 3 This macro is normally used right after the class definition for \a ClassName, in a header file. See the diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index f119828e8e..dc231a00f8 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -711,6 +711,20 @@ QThread::Priority QThread::priority() const \sa terminate() */ +/*! + \since 5.5 + Returns the current event loop level for the thread. + + \note This can only be called within the thread itself, i.e. when + it is the current thread. +*/ + +int QThread::loopLevel() const +{ + Q_D(const QThread); + return d->data->eventLoops.size(); +} + #else // QT_NO_THREAD QThread::QThread(QObject *parent) diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h index 72d8f5a5f8..58755b9625 100644 --- a/src/corelib/thread/qthread.h +++ b/src/corelib/thread/qthread.h @@ -90,6 +90,7 @@ public: void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher); bool event(QEvent *event) Q_DECL_OVERRIDE; + int loopLevel() const; public Q_SLOTS: void start(Priority = InheritPriority); diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index e5fbf5af5e..505a6f863b 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -560,22 +560,6 @@ int QDate::daysInYear() const January 2000 has week number 52 in the year 1999, and 31 December 2002 has week number 1 in the year 2003. - \legalese - Copyright (c) 1989 The Regents of the University of California. - All rights reserved. - - Redistribution and use in source and binary forms are permitted - provided that the above copyright notice and this paragraph are - duplicated in all such forms and that any documentation, - advertising materials, and other materials related to such - distribution and use acknowledge that the software was developed - by the University of California, Berkeley. The name of the - University may not be used to endorse or promote products derived - from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - \sa isValid() */ @@ -585,46 +569,29 @@ int QDate::weekNumber(int *yearNumber) const return 0; int year = QDate::year(); - int yday = dayOfYear() - 1; + int yday = dayOfYear(); int wday = dayOfWeek(); - if (wday == 7) - wday = 0; - int w; - - for (;;) { - int len; - int bot; - int top; - - len = isLeapYear(year) ? 366 : 365; - /* - ** What yday (-3 ... 3) does - ** the ISO year begin on? - */ - bot = ((yday + 11 - wday) % 7) - 3; - /* - ** What yday does the NEXT - ** ISO year begin on? - */ - top = bot - (len % 7); - if (top < -3) - top += 7; - top += len; - if (yday >= top) { + + int week = (yday - wday + 10) / 7; + + if (week == 0) { + // last week of previous year + --year; + week = (yday + 365 + (QDate::isLeapYear(year) ? 1 : 0) - wday + 10) / 7; + Q_ASSERT(week == 52 || week == 53); + } else if (week == 53) { + // maybe first week of next year + int w = (yday - 365 - (QDate::isLeapYear(year + 1) ? 1 : 0) - wday + 10) / 7; + if (w > 0) { ++year; - w = 1; - break; + week = w; } - if (yday >= bot) { - w = 1 + ((yday - bot) / 7); - break; - } - --year; - yday += isLeapYear(year) ? 366 : 365; + Q_ASSERT(week == 53 || week == 1); } + if (yearNumber != 0) *yearNumber = year; - return w; + return week; } #ifndef QT_NO_TEXTDATE @@ -2473,11 +2440,12 @@ static bool epochMSecsToLocalTime(qint64 msecs, QDate *localDate, QTime *localTi } } -// Convert a LocalTime expressed in local msecs encoding into a UTC epoch msecs -// Optionally populate the returned values from mktime for the adjusted local -// date and time and daylight status. Uses daylightStatus in calculation if populated. -static qint64 localMSecsToEpochMSecs(qint64 localMsecs, QDate *localDate = 0, QTime *localTime = 0, - QDateTimePrivate::DaylightStatus *daylightStatus = 0, +// Convert a LocalTime expressed in local msecs encoding and the corresponding +// daylight status into a UTC epoch msecs. Optionally populate the returned +// values from mktime for the adjusted local date and time. +static qint64 localMSecsToEpochMSecs(qint64 localMsecs, + QDateTimePrivate::DaylightStatus *daylightStatus, + QDate *localDate = 0, QTime *localTime = 0, QString *abbreviation = 0, bool *ok = 0) { QDate dt; @@ -2713,9 +2681,11 @@ qint64 QDateTimePrivate::toMSecsSinceEpoch() const case Qt::UTC: return (m_msecs - (m_offsetFromUtc * 1000)); - case Qt::LocalTime: + case Qt::LocalTime: { // recalculate the local timezone - return localMSecsToEpochMSecs(m_msecs); + DaylightStatus status = daylightStatus(); + return localMSecsToEpochMSecs(m_msecs, &status); + } case Qt::TimeZone: #ifndef QT_BOOTSTRAPPED @@ -2785,7 +2755,7 @@ void QDateTimePrivate::refreshDateTime() qint64 epochMSecs = 0; if (m_spec == Qt::LocalTime) { DaylightStatus status = daylightStatus(); - epochMSecs = localMSecsToEpochMSecs(m_msecs, &testDate, &testTime, &status); + epochMSecs = localMSecsToEpochMSecs(m_msecs, &status, &testDate, &testTime); #ifndef QT_BOOTSTRAPPED } else { epochMSecs = zoneMSecsToEpochMSecs(m_msecs, m_timeZone, &testDate, &testTime); @@ -3223,7 +3193,7 @@ QString QDateTime::timeZoneAbbreviation() const case Qt::LocalTime: { QString abbrev; QDateTimePrivate::DaylightStatus status = d->daylightStatus(); - localMSecsToEpochMSecs(d->m_msecs, 0, 0, &status, &abbrev); + localMSecsToEpochMSecs(d->m_msecs, &status, 0, 0, &abbrev); return abbrev; } } @@ -3254,7 +3224,7 @@ bool QDateTime::isDaylightTime() const case Qt::LocalTime: { QDateTimePrivate::DaylightStatus status = d->daylightStatus(); if (status == QDateTimePrivate::UnknownDaylightTime) - localMSecsToEpochMSecs(d->m_msecs, 0, 0, &status, 0); + localMSecsToEpochMSecs(d->m_msecs, &status); return (status == QDateTimePrivate::DaylightTime); } } @@ -3469,6 +3439,7 @@ void QDateTime::setMSecsSinceEpoch(qint64 msecs) epochMSecsToLocalTime(msecs, &dt, &tm, &status); d->setDateTime(dt, tm); d->setDaylightStatus(status); + d->refreshDateTime(); break; } } @@ -3708,12 +3679,14 @@ QDateTime QDateTime::addDays(qint64 ndays) const date = date.addDays(ndays); // Result might fall into "missing" DaylightTime transition hour, // so call conversion and use the adjusted returned time - if (d->m_spec == Qt::LocalTime) - localMSecsToEpochMSecs(timeToMSecs(date, time), &date, &time); + if (d->m_spec == Qt::LocalTime) { + QDateTimePrivate::DaylightStatus status = d->daylightStatus(); + localMSecsToEpochMSecs(timeToMSecs(date, time), &status, &date, &time); #ifndef QT_BOOTSTRAPPED - else if (d->m_spec == Qt::TimeZone) + } else if (d->m_spec == Qt::TimeZone) { QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(date, time), d->m_timeZone, &date, &time); #endif // QT_BOOTSTRAPPED + } dt.d->setDateTime(date, time); return dt; } @@ -3742,12 +3715,14 @@ QDateTime QDateTime::addMonths(int nmonths) const date = date.addMonths(nmonths); // Result might fall into "missing" DaylightTime transition hour, // so call conversion and use the adjusted returned time - if (d->m_spec == Qt::LocalTime) - localMSecsToEpochMSecs(timeToMSecs(date, time), &date, &time); + if (d->m_spec == Qt::LocalTime) { + QDateTimePrivate::DaylightStatus status = d->daylightStatus(); + localMSecsToEpochMSecs(timeToMSecs(date, time), &status, &date, &time); #ifndef QT_BOOTSTRAPPED - else if (d->m_spec == Qt::TimeZone) + } else if (d->m_spec == Qt::TimeZone) { QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(date, time), d->m_timeZone, &date, &time); #endif // QT_BOOTSTRAPPED + } dt.d->setDateTime(date, time); return dt; } @@ -3776,12 +3751,14 @@ QDateTime QDateTime::addYears(int nyears) const date = date.addYears(nyears); // Result might fall into "missing" DaylightTime transition hour, // so call conversion and use the adjusted returned time - if (d->m_spec == Qt::LocalTime) - localMSecsToEpochMSecs(timeToMSecs(date, time), &date, &time); + if (d->m_spec == Qt::LocalTime) { + QDateTimePrivate::DaylightStatus status = d->daylightStatus(); + localMSecsToEpochMSecs(timeToMSecs(date, time), &status, &date, &time); #ifndef QT_BOOTSTRAPPED - else if (d->m_spec == Qt::TimeZone) + } else if (d->m_spec == Qt::TimeZone) { QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(date, time), d->m_timeZone, &date, &time); #endif // QT_BOOTSTRAPPED + } dt.d->setDateTime(date, time); return dt; } diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index b3bc12639e..8998b22be8 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. -** Copyright (C) 2013 Intel Corporation +** Copyright (C) 2015 Intel Corporation ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -158,7 +158,7 @@ static inline bool qt_ends_with(const QChar *haystack, int haystackLen, static inline bool qt_ends_with(const QChar *haystack, int haystackLen, QLatin1String needle, Qt::CaseSensitivity cs); -#ifdef Q_COMPILER_LAMBDA +#if defined(Q_COMPILER_LAMBDA) && !defined(__OPTIMIZE_SIZE__) namespace { template <uint MaxCount> struct UnrollTailLoop { @@ -239,7 +239,7 @@ void qt_from_latin1(ushort *dst, const char *str, size_t size) size = size % 16; dst += offset; str += offset; -# ifdef Q_COMPILER_LAMBDA +# if defined(Q_COMPILER_LAMBDA) && !defined(__OPTIMIZE_SIZE__) return UnrollTailLoop<15>::exec(int(size), [=](int i) { dst[i] = (uchar)str[i]; }); # endif #endif @@ -332,7 +332,7 @@ static void qt_to_latin1(uchar *dst, const ushort *src, int length) dst += offset; src += offset; -# ifdef Q_COMPILER_LAMBDA +# if defined(Q_COMPILER_LAMBDA) && !defined(__OPTIMIZE_SIZE__) return UnrollTailLoop<15>::exec(length, [=](int i) { dst[i] = (src[i]>0xff) ? '?' : (uchar) src[i]; }); # endif #elif defined(__ARM_NEON__) @@ -470,7 +470,7 @@ static int ucstrncmp(const QChar *a, const QChar *b, int l) - reinterpret_cast<const QChar *>(ptr + distance + idx)->unicode(); } } -# ifdef Q_COMPILER_LAMBDA +# if defined(Q_COMPILER_LAMBDA) && !defined(__OPTIMIZE_SIZE__) const auto &lambda = [=](int i) -> int { return reinterpret_cast<const QChar *>(ptr)[i].unicode() - reinterpret_cast<const QChar *>(ptr + distance)[i].unicode(); @@ -602,7 +602,7 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l) uc += offset; c += offset; -# ifdef Q_COMPILER_LAMBDA +# if defined(Q_COMPILER_LAMBDA) && !defined(__OPTIMIZE_SIZE__) const auto &lambda = [=](int i) { return uc[i] - ushort(c[i]); }; return UnrollTailLoop<MaxTailLength>::exec(e - uc, 0, lambda, lambda); # endif @@ -684,7 +684,7 @@ static int findChar(const QChar *str, int len, QChar ch, int from, } } -# ifdef Q_COMPILER_LAMBDA +# if defined(Q_COMPILER_LAMBDA) && !defined(__OPTIMIZE_SIZE__) return UnrollTailLoop<7>::exec(e - n, -1, [=](int i) { return n[i] == c; }, [=](int i) { return n - s + i; }); @@ -4797,11 +4797,11 @@ QString QString::trimmed_helper(QString &str) \overload operator[]() Returns the character at the specified \a position in the string as a -modifiable reference. Equivalent to \c at(position). +modifiable reference. */ /*! \fn const QChar QString::operator[](uint position) const - + Equivalent to \c at(position). \overload operator[]() */ diff --git a/src/corelib/tools/qstringalgorithms_p.h b/src/corelib/tools/qstringalgorithms_p.h index b4be5c7ec7..65901b0286 100644 --- a/src/corelib/tools/qstringalgorithms_p.h +++ b/src/corelib/tools/qstringalgorithms_p.h @@ -120,21 +120,23 @@ template <typename StringType> struct QStringAlgorithms Char *dst = const_cast<Char *>(result.cbegin()); Char *ptr = dst; + bool unmodified = true; forever { while (src != end && isSpace(*src)) ++src; while (src != end && !isSpace(*src)) *ptr++ = *src++; - if (src != end) - *ptr++ = QChar::Space; - else + if (src == end) break; + if (*src != QChar::Space) + unmodified = false; + *ptr++ = QChar::Space; } if (ptr != dst && ptr[-1] == QChar::Space) --ptr; int newlen = ptr - dst; - if (isConst && newlen == str.size()) { + if (isConst && newlen == str.size() && unmodified) { // nothing happened, return the original return str; } diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 6a2a657714..d7fa748a37 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -91,7 +91,7 @@ static inline QString dbusInterfaceString() static inline QDebug operator<<(QDebug dbg, const QThread *th) { - dbg.nospace() << "QThread(ptr=" << (void*)th; + dbg.nospace() << "QThread(ptr=" << (const void*)th; if (th && !th->objectName().isEmpty()) dbg.nospace() << ", name=" << th->objectName(); else if (th) @@ -104,7 +104,7 @@ static inline QDebug operator<<(QDebug dbg, const QThread *th) static inline QDebug operator<<(QDebug dbg, const QDBusConnectionPrivate *conn) { dbg.nospace() << "QDBusConnection(" - << "ptr=" << (void*)conn + << "ptr=" << (const void*)conn << ", name=" << conn->name << ", baseService=" << conn->baseService << ", thread="; diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 18af0e8092..fb30b5f8ee 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -1718,7 +1718,7 @@ Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAccessibleInterface *iface) return d; } d.nospace(); - d << "QAccessibleInterface(" << hex << (void *) iface << dec; + d << "QAccessibleInterface(" << hex << (const void *) iface << dec; if (iface->isValid()) { d << " name=" << iface->text(QAccessible::Name) << " "; d << "role=" << qAccessibleRoleString(iface->role()) << " "; diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri index 7022a6efd0..8db944e5e3 100644 --- a/src/gui/image/image.pri +++ b/src/gui/image/image.pri @@ -80,6 +80,8 @@ contains(QT_CONFIG, gif):include($$PWD/qgifhandler.pri) # SIMD SSE2_SOURCES += image/qimage_sse2.cpp SSSE3_SOURCES += image/qimage_ssse3.cpp +SSE4_1_SOURCES += image/qimage_sse4.cpp +AVX2_SOURCES += image/qimage_avx2.cpp NEON_SOURCES += image/qimage_neon.cpp MIPS_DSPR2_SOURCES += image/qimage_mips_dspr2.cpp MIPS_DSPR2_ASM += image/qimage_mips_dspr2_asm.S diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index 61353ebe6d..7a491d8736 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -639,7 +639,7 @@ bool qt_write_dib(QDataStream &s, QImage image) if (nbits == 1 || nbits == 8) { // direct output for (y=image.height()-1; y>=0; y--) { - if (d->write((char*)image.constScanLine(y), bpl) == -1) + if (d->write((const char*)image.constScanLine(y), bpl) == -1) return false; } return true; diff --git a/src/gui/image/qicon_p.h b/src/gui/image/qicon_p.h index e0fec112b5..8b42e770fa 100644 --- a/src/gui/image/qicon_p.h +++ b/src/gui/image/qicon_p.h @@ -99,7 +99,7 @@ inline QPixmapIconEngineEntry::QPixmapIconEngineEntry(const QString &file, const pixmap.setDevicePixelRatio(1.0); } -class QPixmapIconEngine : public QIconEngine { +class Q_GUI_EXPORT QPixmapIconEngine : public QIconEngine { public: QPixmapIconEngine(); QPixmapIconEngine(const QPixmapIconEngine &); diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index e33ab24243..8ca58d4e5e 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -1433,6 +1433,10 @@ void QImage::setDevicePixelRatio(qreal scaleFactor) { if (!d) return; + + if (scaleFactor == d->devicePixelRatio) + return; + detach(); d->devicePixelRatio = scaleFactor; } @@ -2049,7 +2053,7 @@ static QImage convertWithPalette(const QImage &src, QImage::Format format, if (format == QImage::Format_Indexed8) { for (int y=0; y<h; ++y) { - QRgb *src_pixels = (QRgb *) src.scanLine(y); + const QRgb *src_pixels = (const QRgb *) src.scanLine(y); uchar *dest_pixels = (uchar *) dest.scanLine(y); for (int x=0; x<w; ++x) { int src_pixel = src_pixels[x]; @@ -2065,7 +2069,7 @@ static QImage convertWithPalette(const QImage &src, QImage::Format format, QVector<QRgb> table = clut; table.resize(2); for (int y=0; y<h; ++y) { - QRgb *src_pixels = (QRgb *) src.scanLine(y); + const QRgb *src_pixels = (const QRgb *) src.scanLine(y); for (int x=0; x<w; ++x) { int src_pixel = src_pixels[x]; int value = cache.value(src_pixel, -1); @@ -2676,7 +2680,7 @@ QImage QImage::createHeuristicMask(bool clipTight) const return img32.createHeuristicMask(clipTight); } -#define PIX(x,y) (*((QRgb*)scanLine(y)+x) & 0x00ffffff) +#define PIX(x,y) (*((const QRgb*)scanLine(y)+x) & 0x00ffffff) int w = width(); int h = height(); @@ -2710,7 +2714,7 @@ QImage QImage::createHeuristicMask(bool clipTight) const ypp = ypc; ypc = ypn; ypn = (y == h-1) ? 0 : m.scanLine(y+1); - QRgb *p = (QRgb *)scanLine(y); + const QRgb *p = (const QRgb *)scanLine(y); for (x = 0; x < w; x++) { // slowness here - it's possible to do six of these tests // together in one go. oh well. @@ -2736,7 +2740,7 @@ QImage QImage::createHeuristicMask(bool clipTight) const ypp = ypc; ypc = ypn; ypn = (y == h-1) ? 0 : m.scanLine(y+1); - QRgb *p = (QRgb *)scanLine(y); + const QRgb *p = (const QRgb *)scanLine(y); for (x = 0; x < w; x++) { if ((*p & 0x00ffffff) != background) { if (x > 0) @@ -2780,7 +2784,7 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const if (depth() == 32) { for (int h = 0; h < d->height; h++) { - const uint *sl = (uint *) scanLine(h); + const uint *sl = (const uint *) scanLine(h); for (int w = 0; w < d->width; w++) { if (sl[w] == color) *(s + (w >> 3)) |= (1 << (w & 7)); @@ -3873,7 +3877,7 @@ bool qt_xForm_helper(const QTransform &trueMat, int xoffset, int type, int depth case 16: // 16 bpp transform while (dptr < maxp) { if (trigx < maxws && trigy < maxhs) - *((ushort*)dptr) = *((ushort *)(sptr+sbpl*(trigy>>12) + + *((ushort*)dptr) = *((const ushort *)(sptr+sbpl*(trigy>>12) + ((trigx>>12)<<1))); trigx += m11; trigy += m12; @@ -3899,7 +3903,7 @@ bool qt_xForm_helper(const QTransform &trueMat, int xoffset, int type, int depth case 32: // 32 bpp transform while (dptr < maxp) { if (trigx < maxws && trigy < maxhs) - *((uint*)dptr) = *((uint *)(sptr+sbpl*(trigy>>12) + + *((uint*)dptr) = *((const uint *)(sptr+sbpl*(trigy>>12) + ((trigx>>12)<<2))); trigx += m11; trigy += m12; @@ -4046,7 +4050,7 @@ void QImage::setAlphaChannel(const QImage &alphaChannel) // Slight optimization since alphachannels are returned as 8-bit grays. if (alphaChannel.format() == QImage::Format_Alpha8 ||( alphaChannel.d->depth == 8 && alphaChannel.isGrayscale())) { const uchar *src_data = alphaChannel.d->data; - const uchar *dest_data = d->data; + uchar *dest_data = d->data; for (int y=0; y<h; ++y) { const uchar *src = src_data; QRgb *dest = (QRgb *)dest_data; @@ -4067,7 +4071,7 @@ void QImage::setAlphaChannel(const QImage &alphaChannel) } else { const QImage sourceImage = alphaChannel.convertToFormat(QImage::Format_RGB32); const uchar *src_data = sourceImage.d->data; - const uchar *dest_data = d->data; + uchar *dest_data = d->data; for (int y=0; y<h; ++y) { const QRgb *src = (const QRgb *) src_data; QRgb *dest = (QRgb *) dest_data; diff --git a/src/gui/image/qimage_avx2.cpp b/src/gui/image/qimage_avx2.cpp new file mode 100644 index 0000000000..c52baec948 --- /dev/null +++ b/src/gui/image/qimage_avx2.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2015 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 <qimage.h> +#include <private/qdrawhelper_p.h> +#include <private/qimage_p.h> +#include <private/qsimd_p.h> + +#ifdef QT_COMPILER_SUPPORTS_AVX2 + +QT_BEGIN_NAMESPACE + +void convert_ARGB_to_ARGB_PM_avx2(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888); + Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || dest->format == QImage::Format_RGBA8888_Premultiplied); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const uint *src_data = (uint *) src->data; + uint *dest_data = (uint *) dest->data; + for (int i = 0; i < src->height; ++i) { + qt_convertARGB32ToARGB32PM(dest_data, src_data, src->width); + src_data += src->bytes_per_line >> 2; + dest_data += dest->bytes_per_line >> 2; + } +} + +QT_END_NAMESPACE + +#endif // QT_COMPILER_SUPPORTS_AVX2 diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 5103d820d6..417c185c78 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -32,7 +32,6 @@ ****************************************************************************/ #include <private/qdrawhelper_p.h> -#include <private/qdrawingprimitive_sse2_p.h> #include <private/qguiapplication_p.h> #include <private/qsimd_p.h> #include <private/qimage_p.h> @@ -110,17 +109,6 @@ static const uint *QT_FASTCALL convertRGB32FromARGB32PM(uint *buffer, const uint return buffer; } -#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) -QT_FUNCTION_TARGET(SSE4_1) -static const uint *QT_FASTCALL convertRGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count, - const QPixelLayout *, const QRgb *) -{ - for (int i = 0; i < count; ++i) - buffer[i] = 0xff000000 | qUnpremultiply_sse4(src[i]); - return buffer; -} -#endif - static const uint *QT_FASTCALL convertRGB32ToARGB32PM(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *) { @@ -129,6 +117,10 @@ static const uint *QT_FASTCALL convertRGB32ToARGB32PM(uint *buffer, const uint * return buffer; } +#ifdef QT_COMPILER_SUPPORTS_SSE4_1 +extern const uint *QT_FASTCALL convertRGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); +#endif + void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { // Cannot be used with indexed formats. @@ -152,7 +144,7 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio if (src->format == QImage::Format_RGB32) convertToARGB32PM = convertRGB32ToARGB32PM; if (dest->format == QImage::Format_RGB32) { -#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) +#ifdef QT_COMPILER_SUPPORTS_SSE4_1 if (qCpuHasFeature(SSE4_1)) convertFromARGB32PM = convertRGB32FromARGB32PM_sse4; else @@ -201,7 +193,7 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im if (data->format == QImage::Format_RGB32) convertToARGB32PM = convertRGB32ToARGB32PM; if (dst_format == QImage::Format_RGB32) { -#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) +#ifdef QT_COMPILER_SUPPORTS_SSE4_1 if (qCpuHasFeature(SSE4_1)) convertFromARGB32PM = convertRGB32FromARGB32PM_sse4; else @@ -257,7 +249,7 @@ static bool convert_passthrough_inplace(QImageData *data, Qt::ImageConversionFla return true; } -static inline void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888); Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || dest->format == QImage::Format_RGBA8888_Premultiplied); @@ -281,15 +273,6 @@ static inline void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *s } } -#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) && !defined(__SSE4_1__) -QT_FUNCTION_TARGET(SSE4_1) -static void convert_ARGB_to_ARGB_PM_sse4(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags) -{ - // Twice as fast autovectorized due to SSE4.1 PMULLD instructions. - convert_ARGB_to_ARGB_PM(dest, src, flags); -} -#endif - Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32(quint32 *dest_data, const uchar *src_data, int len) { int pixel = 0; @@ -303,7 +286,7 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32(quint32 *dest_data, con // Handle 4 pixels at a time 12 bytes input to 16 bytes output. for (; pixel + 3 < len; pixel += 4) { - const quint32 *src_packed = (quint32 *) src_data; + const quint32 *src_packed = (const quint32 *) src_data; const quint32 src1 = qFromBigEndian(src_packed[0]); const quint32 src2 = qFromBigEndian(src_packed[1]); const quint32 src3 = qFromBigEndian(src_packed[2]); @@ -338,7 +321,7 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgbx8888(quint32 *dest_data, // Handle 4 pixels at a time 12 bytes input to 16 bytes output. for (; pixel + 3 < len; pixel += 4) { - const quint32 *src_packed = (quint32 *) src_data; + const quint32 *src_packed = (const quint32 *) src_data; const quint32 src1 = src_packed[0]; const quint32 src2 = src_packed[1]; const quint32 src3 = src_packed[2]; @@ -1109,12 +1092,12 @@ void dither_to_Mono(QImageData *dst, const QImageData *src, } else { // 32 bit image if (fromalpha) { while (p < end) { - *b2++ = 255 - (*(uint*)p >> 24); + *b2++ = 255 - (*(const uint*)p >> 24); p += 4; } } else { while (p < end) { - *b2++ = qGray(*(uint*)p); + *b2++ = qGray(*(const uint*)p); p += 4; } } @@ -1132,12 +1115,12 @@ void dither_to_Mono(QImageData *dst, const QImageData *src, } else { // 24 bit image if (fromalpha) { while (p < end) { - *b2++ = 255 - (*(uint*)p >> 24); + *b2++ = 255 - (*(const uint*)p >> 24); p += 4; } } else { while (p < end) { - *b2++ = qGray(*(uint*)p); + *b2++ = qGray(*(const uint*)p); p += 4; } } @@ -2804,13 +2787,22 @@ void qInitImageConversions() } #endif -#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) && !defined(__SSE4_1__) +#if defined(QT_COMPILER_SUPPORTS_SSE4_1) && !defined(__SSE4_1__) if (qCpuHasFeature(SSE4_1)) { + extern void convert_ARGB_to_ARGB_PM_sse4(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); qimage_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_sse4; qimage_converter_map[QImage::Format_RGBA8888][QImage::Format_RGBA8888_Premultiplied] = convert_ARGB_to_ARGB_PM_sse4; } #endif +#if defined(QT_COMPILER_SUPPORTS_AVX2) && !defined(__AVX2__) + if (qCpuHasFeature(AVX2)) { + extern void convert_ARGB_to_ARGB_PM_avx2(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); + qimage_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_avx2; + qimage_converter_map[QImage::Format_RGBA8888][QImage::Format_RGBA8888_Premultiplied] = convert_ARGB_to_ARGB_PM_avx2; + } +#endif + #if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64) extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon; diff --git a/src/gui/image/qimage_sse4.cpp b/src/gui/image/qimage_sse4.cpp new file mode 100644 index 0000000000..5fad4f572a --- /dev/null +++ b/src/gui/image/qimage_sse4.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2015 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 <qimage.h> +#include <private/qdrawhelper_p.h> +#include <private/qdrawingprimitive_sse2_p.h> +#include <private/qimage_p.h> +#include <private/qsimd_p.h> + +#ifdef QT_COMPILER_SUPPORTS_SSE4_1 + +QT_BEGIN_NAMESPACE + +const uint *QT_FASTCALL convertRGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = 0xff000000 | qUnpremultiply_sse4(src[i]); + return buffer; +} + +void convert_ARGB_to_ARGB_PM_sse4(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888); + Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || dest->format == QImage::Format_RGBA8888_Premultiplied); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const uint *src_data = (uint *) src->data; + uint *dest_data = (uint *) dest->data; + for (int i = 0; i < src->height; ++i) { + qt_convertARGB32ToARGB32PM(dest_data, src_data, src->width); + src_data += src->bytes_per_line >> 2; + dest_data += dest->bytes_per_line >> 2; + } +} + +QT_END_NAMESPACE + +#endif // QT_COMPILER_SUPPORTS_SSE4_1 diff --git a/src/gui/image/qimage_ssse3.cpp b/src/gui/image/qimage_ssse3.cpp index 0f8244689e..4597661776 100644 --- a/src/gui/image/qimage_ssse3.cpp +++ b/src/gui/image/qimage_ssse3.cpp @@ -65,7 +65,7 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, con // Mask to have alpha = 0xff const __m128i alphaMask = _mm_set1_epi32(0xff000000); - __m128i *inVectorPtr = (__m128i *)src; + const __m128i *inVectorPtr = (const __m128i *)src; __m128i *dstVectorPtr = (__m128i *)dst; const int simdRoundCount = (len - prologLength) / 16; // one iteration in the loop converts 16 pixels @@ -110,7 +110,7 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, con _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask)); ++dstVectorPtr; } - src = (uchar *)inVectorPtr; + src = (const uchar *)inVectorPtr; dst = (quint32 *)dstVectorPtr; while (dst != end) { diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index b1146c4297..aff7b79807 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -514,7 +514,7 @@ static inline void set_text(const QImage &image, j_compress_ptr cinfo, const QSt comment += it.value().toLatin1(); if (comment.length() > 65530) comment.truncate(65530); - jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *)comment.constData(), comment.size()); + jpeg_write_marker(cinfo, JPEG_COM, (const JOCTET *)comment.constData(), comment.size()); } } diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index 8b62183c20..b63be19153 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -1362,7 +1362,7 @@ void QPictureIO::init() QPictureIO::~QPictureIO() { if (d->parameters) - delete [] (char*)d->parameters; + delete [] d->parameters; delete d; } @@ -1671,7 +1671,7 @@ const char *QPictureIO::parameters() const void QPictureIO::setParameters(const char *parameters) { if (d->parameters) - delete [] (char*)d->parameters; + delete [] d->parameters; d->parameters = qstrdup(parameters); } diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 0a9b55ed24..db6ae54d26 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -682,6 +682,9 @@ void QPixmap::setDevicePixelRatio(qreal scaleFactor) if (isNull()) return; + if (scaleFactor == data->devicePixelRatio()) + return; + detach(); data->setDevicePixelRatio(scaleFactor); } diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index c3ffd00e15..3c88d2e9c1 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -942,7 +942,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, vo // 0123456789aBC data[0xB] = looping%0x100; data[0xC] = looping/0x100; - png_write_chunk(png_ptr, (png_byte*)"gIFx", data, 13); + png_write_chunk(png_ptr, const_cast<png_bytep>((const png_byte *)"gIFx"), data, 13); } if (ms_delay >= 0 || disposal!=Unspecified) { uchar data[4]; @@ -950,7 +950,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, vo data[1] = 0; data[2] = (ms_delay/10)/0x100; // hundredths data[3] = (ms_delay/10)%0x100; - png_write_chunk(png_ptr, (png_byte*)"gIFg", data, 4); + png_write_chunk(png_ptr, const_cast<png_bytep>((const png_byte *)"gIFg"), data, 4); } int height = image.height(); @@ -966,7 +966,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, vo { png_bytep* row_pointers = new png_bytep[height]; for (int y=0; y<height; y++) - row_pointers[y] = (png_bytep)image.constScanLine(y); + row_pointers[y] = const_cast<png_bytep>(image.constScanLine(y)); png_write_image(png_ptr, row_pointers); delete [] row_pointers; } @@ -978,7 +978,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, vo png_bytep row_pointers[1]; for (int y=0; y<height; y++) { row = image.copy(0, y, width, 1).convertToFormat(fmt); - row_pointers[0] = png_bytep(row.constScanLine(0)); + row_pointers[0] = const_cast<png_bytep>(row.constScanLine(0)); png_write_rows(png_ptr, row_pointers, 1); } } diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp index 954efa38ed..7e073370f2 100644 --- a/src/gui/kernel/qcursor.cpp +++ b/src/gui/kernel/qcursor.cpp @@ -33,8 +33,6 @@ #include "qcursor.h" -#ifndef QT_NO_CURSOR - #include <qcoreapplication.h> #include <qbitmap.h> #include <qimage.h> @@ -259,6 +257,8 @@ void QCursor::setPos(int x, int y) QCursor::setPos(QGuiApplication::primaryScreen(), x, y); } +#ifndef QT_NO_CURSOR + /*! \fn void QCursor::setPos (const QPoint &p) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 8c49b3a2b5..3d21b4affc 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -147,12 +147,15 @@ QString *QGuiApplicationPrivate::displayName = 0; QPalette *QGuiApplicationPrivate::app_pal = 0; // default application palette Qt::MouseButtons QGuiApplicationPrivate::buttons = Qt::NoButton; + ulong QGuiApplicationPrivate::mousePressTime = 0; Qt::MouseButton QGuiApplicationPrivate::mousePressButton = Qt::NoButton; int QGuiApplicationPrivate::mousePressX = 0; int QGuiApplicationPrivate::mousePressY = 0; int QGuiApplicationPrivate::mouse_double_click_distance = -1; +QWindow *QGuiApplicationPrivate::currentMousePressWindow = 0; + static Qt::LayoutDirection layout_direction = Qt::LeftToRight; static bool force_reverse = false; @@ -1703,6 +1706,17 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo if (e->nullWindow()) { window = QGuiApplication::topLevelAt(globalPoint.toPoint()); if (window) { + // Moves and the release following a press must go to the same + // window, even if the cursor has moved on over another window. + if (e->buttons != Qt::NoButton) { + if (!currentMousePressWindow) + currentMousePressWindow = window; + else + window = currentMousePressWindow; + } else if (currentMousePressWindow) { + window = currentMousePressWindow; + currentMousePressWindow = 0; + } QPointF delta = globalPoint - globalPoint.toPoint(); localPoint = window->mapFromGlobal(globalPoint.toPoint()) + delta; } @@ -2554,7 +2568,7 @@ void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate: } if (availableGeometryChanged) - emit s->availableGeometryChanged(s->geometry()); + emit s->availableGeometryChanged(s->availableGeometry()); if (geometryChanged || availableGeometryChanged) { foreach (QScreen* sibling, s->virtualSiblings()) diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 0c00e06499..7ae6e64b26 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -200,6 +200,7 @@ public: static Qt::MouseButtons tabletState; static QWindow *tabletPressTarget; static QWindow *currentMouseWindow; + static QWindow *currentMousePressWindow; static Qt::ApplicationState applicationState; #ifndef QT_NO_CLIPBOARD diff --git a/src/gui/kernel/qinputdevicemanager.cpp b/src/gui/kernel/qinputdevicemanager.cpp index 1a3e6b8119..d0dd8a4e7c 100644 --- a/src/gui/kernel/qinputdevicemanager.cpp +++ b/src/gui/kernel/qinputdevicemanager.cpp @@ -36,6 +36,25 @@ QT_BEGIN_NAMESPACE +/*! + \class QInputDeviceManager + \internal + + \brief QInputDeviceManager acts as a communication hub between QtGui and the input handlers. + + On embedded platforms the input handling code is either compiled into the platform + plugin or is loaded dynamically as a generic plugin without any interface. The input + handler in use may also change between each run (e.g. evdevmouse/keyboard/touch + vs. libinput). QWindowSystemInterface is too limiting when Qt (the platform plugin) is + acting as a windowing system, and is one way only. + + QInputDeviceManager solves this by providing a global object that is used to communicate + from the input handlers to the rest of Qt (e.g. the number of connected mice, which may + be important information for the cursor drawing code), and vice-versa (e.g. to indicate + to the input handler that a manual cursor position change was requested by the + application via QCursor::setPos and thus any internal state has to be updated accordingly). +*/ + QInputDeviceManager::QInputDeviceManager(QObject *parent) : QObject(*new QInputDeviceManagerPrivate, parent) { @@ -61,4 +80,9 @@ void QInputDeviceManagerPrivate::setDeviceCount(QInputDeviceManager::DeviceType } } +void QInputDeviceManager::setCursorPos(const QPoint &pos) +{ + emit cursorPositionChangeRequested(pos); +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qinputdevicemanager_p.h b/src/gui/kernel/qinputdevicemanager_p.h index cc55c8b4e5..15c84d1a82 100644 --- a/src/gui/kernel/qinputdevicemanager_p.h +++ b/src/gui/kernel/qinputdevicemanager_p.h @@ -68,8 +68,11 @@ public: int deviceCount(DeviceType type) const; + void setCursorPos(const QPoint &pos); + signals: void deviceListChanged(DeviceType type); + void cursorPositionChangeRequested(const QPoint &pos); }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp index 7da95ffcec..2749b05691 100644 --- a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp +++ b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp @@ -112,6 +112,7 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe bool *swizzleRandB, const QRect &subRect) { +#ifndef QT_NO_OPENGL if (!QOpenGLContext::currentContext()) return false; @@ -172,6 +173,12 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe return true; +#else + Q_UNUSED(graphicsBuffer) + Q_UNUSED(swizzleRandB) + Q_UNUSED(subRect) + return false; +#endif // QT_NO_OPENGL } QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h index 0536c3688c..baa1e460d7 100644 --- a/src/gui/kernel/qplatformmenu.h +++ b/src/gui/kernel/qplatformmenu.h @@ -103,6 +103,7 @@ public: virtual void setText(const QString &text) = 0; virtual void setIcon(const QIcon &icon) = 0; virtual void setEnabled(bool enabled) = 0; + virtual bool isEnabled() const { return true; } virtual void setVisible(bool visible) = 0; virtual void setMinimumWidth(int width) { Q_UNUSED(width); } virtual void setFont(const QFont &font) { Q_UNUSED(font); } diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 06db4e81fa..06674d204d 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -1599,6 +1599,8 @@ void QWindow::destroy() QGuiApplicationPrivate::focus_window = parent(); if (QGuiApplicationPrivate::currentMouseWindow == this) QGuiApplicationPrivate::currentMouseWindow = parent(); + if (QGuiApplicationPrivate::currentMousePressWindow == this) + QGuiApplicationPrivate::currentMousePressWindow = parent(); if (QGuiApplicationPrivate::tabletPressTarget == this) QGuiApplicationPrivate::tabletPressTarget = parent(); diff --git a/src/gui/opengl/qopengl_p.h b/src/gui/opengl/qopengl_p.h index 377440455a..e04ae05120 100644 --- a/src/gui/opengl/qopengl_p.h +++ b/src/gui/opengl/qopengl_p.h @@ -77,6 +77,9 @@ public: struct Gpu { Gpu() : vendorId(0), deviceId(0) {} bool isValid() const { return deviceId; } + bool equals(const Gpu &other) const { + return vendorId == other.vendorId && deviceId == other.deviceId && driverVersion == other.driverVersion; + } uint vendorId; uint deviceId; @@ -93,6 +96,21 @@ public: static QSet<QString> gpuFeatures(const Gpu &gpu, const QString &fileName); }; +inline bool operator==(const QOpenGLConfig::Gpu &a, const QOpenGLConfig::Gpu &b) +{ + return a.equals(b); +} + +inline bool operator!=(const QOpenGLConfig::Gpu &a, const QOpenGLConfig::Gpu &b) +{ + return !a.equals(b); +} + +inline uint qHash(const QOpenGLConfig::Gpu &gpu) +{ + return qHash(gpu.vendorId) + qHash(gpu.deviceId) + qHash(gpu.driverVersion); +} + QT_END_NAMESPACE #endif // QOPENGL_H diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index e87f7bfcef..a9a4adaddc 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -1229,7 +1229,7 @@ void QOpenGL2PaintEngineExPrivate::drawVertexArrays(const float *data, int *stop GLenum primitive) { // Now setup the pointer to the vertex array: - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)data); + setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, data); int previousStop = 0; for (int i=0; i<stopCount; ++i) { diff --git a/src/gui/opengl/qopengltexturehelper.cpp b/src/gui/opengl/qopengltexturehelper.cpp index 386c4af232..3635a7dd1b 100644 --- a/src/gui/opengl/qopengltexturehelper.cpp +++ b/src/gui/opengl/qopengltexturehelper.cpp @@ -40,8 +40,16 @@ QT_BEGIN_NAMESPACE QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context) { - // Resolve EXT_direct_state_access entry points if present - if (!context->isOpenGLES() + // Resolve EXT_direct_state_access entry points if present. + + // However, disable it on some systems where DSA is known to be unreliable. + bool allowDSA = true; + const char *renderer = reinterpret_cast<const char *>(context->functions()->glGetString(GL_RENDERER)); + // QTBUG-40653, QTBUG-44988 + if (renderer && strstr(renderer, "AMD Radeon HD")) + allowDSA = false; + + if (allowDSA && !context->isOpenGLES() && context->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) { TextureParameteriEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , GLint )>(context->getProcAddress(QByteArrayLiteral("glTextureParameteriEXT"))); TextureParameterivEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , const GLint *)>(context->getProcAddress(QByteArrayLiteral("glTextureParameterivEXT"))); diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 0507cc128f..3010d4052a 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -94,6 +94,8 @@ SOURCES += \ SSE2_SOURCES += painting/qdrawhelper_sse2.cpp SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp +SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp +AVX2_SOURCES += painting/qdrawhelper_avx2.cpp !ios { CONFIG += no_clang_integrated_as diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index 1564e25016..478fe6564c 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -245,7 +245,7 @@ static void qt_blend_argb32_on_rgb16(uchar *destPixels, int dbpl, } quint16 *dst = (quint16 *) destPixels; - quint32 *src = (quint32 *) srcPixels; + const quint32 *src = (const quint32 *) srcPixels; for (int y=0; y<h; ++y) { for (int x=0; x<w; ++x) { @@ -282,7 +282,7 @@ static void qt_blend_argb32_on_rgb16(uchar *destPixels, int dbpl, } } dst = (quint16 *) (((uchar *) dst) + dbpl); - src = (quint32 *) (((uchar *) src) + sbpl); + src = (const quint32 *) (((const uchar *) src) + sbpl); } } diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp index 93c95e4a86..f82b098012 100644 --- a/src/gui/painting/qcosmeticstroker.cpp +++ b/src/gui/painting/qcosmeticstroker.cpp @@ -437,8 +437,9 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal int y = (y1 + 32) >> 6; int ys = (y2 + 32) >> 6; + int round = (xinc > 0) ? 32 : 0; if (y != ys) { - x += ( ((((y << 6) + 32 - y1))) * xinc ) >> 6; + x += ( ((((y << 6) + round - y1))) * xinc ) >> 6; if (swapped) { lastPixel.x = x >> 16; @@ -468,8 +469,9 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal int x = (x1 + 32) >> 6; int xs = (x2 + 32) >> 6; + int round = (yinc > 0) ? 32 : 0; if (x != xs) { - y += ( ((((x << 6) + 32 - x1))) * yinc ) >> 6; + y += ( ((((x << 6) + round - x1))) * yinc ) >> 6; if (swapped) { lastPixel.x = x; @@ -762,9 +764,10 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, int y = (y1 + 32) >> 6; int ys = (y2 + 32) >> 6; + int round = (xinc > 0) ? 32 : 0; if (y != ys) { - x += ( ((((y << 6) + 32 - y1))) * xinc ) >> 6; + x += ( ((((y << 6) + round - y1))) * xinc ) >> 6; // calculate first and last pixel and perform dropout control QCosmeticStroker::Point first; @@ -837,9 +840,10 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, int x = (x1 + 32) >> 6; int xs = (x2 + 32) >> 6; + int round = (yinc > 0) ? 32 : 0; if (x != xs) { - y += ( ((((x << 6) + 32 - x1))) * yinc ) >> 6; + y += ( ((((x << 6) + round - x1))) * yinc ) >> 6; // calculate first and last pixel to perform dropout control QCosmeticStroker::Point first; diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 04857fb0d6..538389f15f 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -355,24 +355,11 @@ static const uint *QT_FASTCALL convertPassThrough(uint *, const uint *src, int, return src; } -static inline const uint *QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count, - const QPixelLayout *, const QRgb *) -{ - for (int i = 0; i < count; ++i) - buffer[i] = qPremultiply(src[i]); - return buffer; -} - -#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) && !defined(__SSE4_1__) -QT_FUNCTION_TARGET(SSE4_1) -static const uint *QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, const uint *src, int count, - const QPixelLayout *layout, const QRgb *clut) +static const uint *QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) { - // Twice as fast autovectorized due to SSE4.1 PMULLD instructions. - return convertARGB32ToARGB32PM(buffer, src, count, layout, clut); + return qt_convertARGB32ToARGB32PM(buffer, src, count); } -#endif - static const uint *QT_FASTCALL convertRGBA8888PMToARGB32PM(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *) @@ -382,24 +369,12 @@ static const uint *QT_FASTCALL convertRGBA8888PMToARGB32PM(uint *buffer, const u return buffer; } -static inline const uint *QT_FASTCALL convertRGBA8888ToARGB32PM(uint *buffer, const uint *src, int count, +static const uint *QT_FASTCALL convertRGBA8888ToARGB32PM(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *) { - for (int i = 0; i < count; ++i) - buffer[i] = qPremultiply(RGBA2ARGB(src[i])); - return buffer; + return qt_convertRGBA8888ToARGB32PM(buffer, src, count); } -#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) && !defined(__SSE4_1__) -QT_FUNCTION_TARGET(SSE4_1) -static const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer, const uint *src, int count, - const QPixelLayout *layout, const QRgb *clut) -{ - // Twice as fast autovectorized due to SSE4.1 PMULLD instructions. - return convertRGBA8888ToARGB32PM(buffer, src, count, layout, clut); -} -#endif - static const uint *QT_FASTCALL convertAlpha8ToRGB32(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *) { @@ -424,18 +399,6 @@ static const uint *QT_FASTCALL convertARGB32FromARGB32PM(uint *buffer, const uin return buffer; } -#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) -QT_FUNCTION_TARGET(SSE4_1) -static const uint *QT_FASTCALL convertARGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count, - const QPixelLayout *, const QRgb *) -{ - for (int i = 0; i < count; ++i) - buffer[i] = qUnpremultiply_sse4(src[i]); - return buffer; -} -#endif - - static const uint *QT_FASTCALL convertRGBA8888PMFromARGB32PM(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *) { @@ -452,17 +415,6 @@ static const uint *QT_FASTCALL convertRGBA8888FromARGB32PM(uint *buffer, const u return buffer; } -#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) -QT_FUNCTION_TARGET(SSE4_1) -static const uint *QT_FASTCALL convertRGBA8888FromARGB32PM_sse4(uint *buffer, const uint *src, int count, - const QPixelLayout *, const QRgb *) -{ - for (int i = 0; i < count; ++i) - buffer[i] = ARGB2RGBA(qUnpremultiply_sse4(src[i])); - return buffer; -} -#endif - static const uint *QT_FASTCALL convertRGBXFromRGB32(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *) { @@ -479,17 +431,6 @@ static const uint *QT_FASTCALL convertRGBXFromARGB32PM(uint *buffer, const uint return buffer; } -#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) -QT_FUNCTION_TARGET(SSE4_1) -static const uint *QT_FASTCALL convertRGBXFromARGB32PM_sse4(uint *buffer, const uint *src, int count, - const QPixelLayout *, const QRgb *) -{ - for (int i = 0; i < count; ++i) - buffer[i] = ARGB2RGBA(0xff000000 | qUnpremultiply_sse4(src[i])); - return buffer; -} -#endif - template<QtPixelOrder PixelOrder> static const uint *QT_FASTCALL convertA2RGB30PMToARGB32PM(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *) @@ -1454,7 +1395,7 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c lim -= 3; for (; f < lim; x += 4, f += 4) { // Load 4 pixels from s1, and split the alpha-green and red-blue component - __m128i top = _mm_loadu_si128((__m128i*)((const uint *)(s1)+x)); + __m128i top = _mm_loadu_si128((const __m128i*)((const uint *)(s1)+x)); __m128i topAG = _mm_srli_epi16(top, 8); __m128i topRB = _mm_and_si128(top, colorMask); // Multiplies each colour component by idisty @@ -1462,7 +1403,7 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c topRB = _mm_mullo_epi16 (topRB, idisty_); // Same for the s2 vector - __m128i bottom = _mm_loadu_si128((__m128i*)((const uint *)(s2)+x)); + __m128i bottom = _mm_loadu_si128((const __m128i*)((const uint *)(s2)+x)); __m128i bottomAG = _mm_srli_epi16(bottom, 8); __m128i bottomRB = _mm_and_si128(bottom, colorMask); bottomAG = _mm_mullo_epi16 (bottomAG, disty_); @@ -4741,7 +4682,7 @@ static void blend_untransformed_argb(int count, const QSpan *spans, void *userDa length = image_width - sx; if (length > 0) { const int coverage = (spans->coverage * data->texture.const_alpha) >> 8; - const uint *src = (uint *)data->texture.scanLine(sy) + sx; + const uint *src = (const uint *)data->texture.scanLine(sy) + sx; uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x; op.func(dest, src, length, coverage); } @@ -4840,7 +4781,7 @@ static void blend_untransformed_rgb565(int count, const QSpan *spans, void *user length = image_width - sx; if (length > 0) { quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + x; - const quint16 *src = (quint16 *)data->texture.scanLine(sy) + sx; + const quint16 *src = (const quint16 *)data->texture.scanLine(sy) + sx; if (coverage == 255) { memcpy(dest, src, length * sizeof(quint16)); } else { @@ -4939,7 +4880,7 @@ static void blend_tiled_argb(int count, const QSpan *spans, void *userData) int l = qMin(image_width - sx, length); if (buffer_size < l) l = buffer_size; - const uint *src = (uint *)data->texture.scanLine(sy) + sx; + const uint *src = (const uint *)data->texture.scanLine(sy) + sx; uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x; op.func(dest, src, l, coverage); x += l; @@ -4998,7 +4939,7 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData) if (buffer_size < l) l = buffer_size; quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans->y)) + tx; - const quint16 *src = (quint16 *)data->texture.scanLine(sy) + sx; + const quint16 *src = (const quint16 *)data->texture.scanLine(sy) + sx; memcpy(dest, src, l * sizeof(quint16)); length -= l; tx += l; @@ -5032,7 +4973,7 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData) if (buffer_size < l) l = buffer_size; quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans->y)) + x; - const quint16 *src = (quint16 *)data->texture.scanLine(sy) + sx; + const quint16 *src = (const quint16 *)data->texture.scanLine(sy) + sx; blend_sourceOver_rgb16_rgb16(dest, src, l, alpha, ialpha); x += l; length -= l; @@ -5108,8 +5049,8 @@ static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans, voi fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_minx, src_maxx, x1, x2); fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_miny, src_maxy, y1, y2); - const quint16 *src1 = (quint16*)data->texture.scanLine(y1); - const quint16 *src2 = (quint16*)data->texture.scanLine(y2); + const quint16 *src1 = (const quint16*)data->texture.scanLine(y1); + const quint16 *src2 = (const quint16*)data->texture.scanLine(y2); quint16 tl = src1[x1]; const quint16 tr = src1[x2]; quint16 bl = src2[x1]; @@ -5195,8 +5136,8 @@ static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans, voi fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_minx, src_maxx, x1, x2); fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_miny, src_maxy, y1, y2); - const quint16 *src1 = (quint16 *)data->texture.scanLine(y1); - const quint16 *src2 = (quint16 *)data->texture.scanLine(y2); + const quint16 *src1 = (const quint16 *)data->texture.scanLine(y1); + const quint16 *src2 = (const quint16 *)data->texture.scanLine(y2); quint16 tl = src1[x1]; const quint16 tr = src1[x2]; quint16 bl = src2[x1]; @@ -5392,7 +5333,7 @@ static void blend_transformed_rgb565(int count, const QSpan *spans, void *userDa const int px = qBound(0, x >> 16, image_width - 1); const int py = qBound(0, y >> 16, image_height - 1); - *b = ((quint16 *)data->texture.scanLine(py))[px]; + *b = ((const quint16 *)data->texture.scanLine(py))[px]; ++b; x += fdx; @@ -5451,7 +5392,7 @@ static void blend_transformed_rgb565(int count, const QSpan *spans, void *userDa const int px = qBound(0, int(tx) - (tx < 0), image_width - 1); const int py = qBound(0, int(ty) - (ty < 0), image_height - 1); - *b = ((quint16 *)data->texture.scanLine(py))[px]; + *b = ((const quint16 *)data->texture.scanLine(py))[px]; ++b; x += fdx; @@ -5495,7 +5436,7 @@ static void blend_transformed_tiled_argb(int count, const QSpan *spans, void *us void *t = data->rasterBuffer->scanLine(spans->y); uint *target = ((uint *)t) + spans->x; - uint *image_bits = (uint *)data->texture.imageData; + const uint *image_bits = (const uint *)data->texture.imageData; const qreal cx = spans->x + qreal(0.5); const qreal cy = spans->y + qreal(0.5); @@ -5550,7 +5491,7 @@ static void blend_transformed_tiled_argb(int count, const QSpan *spans, void *us void *t = data->rasterBuffer->scanLine(spans->y); uint *target = ((uint *)t) + spans->x; - uint *image_bits = (uint *)data->texture.imageData; + const uint *image_bits = (const uint *)data->texture.imageData; const qreal cx = spans->x + qreal(0.5); const qreal cy = spans->y + qreal(0.5); @@ -5661,7 +5602,7 @@ static void blend_transformed_tiled_rgb565(int count, const QSpan *spans, void * if (py < 0) py += image_height; - *b = ((quint16 *)data->texture.scanLine(py))[px]; + *b = ((const quint16 *)data->texture.scanLine(py))[px]; ++b; x += fdx; @@ -5727,7 +5668,7 @@ static void blend_transformed_tiled_rgb565(int count, const QSpan *spans, void * if (py < 0) py += image_height; - *b = ((quint16 *)data->texture.scanLine(py))[px]; + *b = ((const quint16 *)data->texture.scanLine(py))[px]; ++b; x += fdx; @@ -6793,18 +6734,32 @@ void qInitDrawhelperAsm() } #endif // SSSE3 -#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) +#if QT_COMPILER_SUPPORTS_SSE4_1 if (qCpuHasFeature(SSE4_1)) { #if !defined(__SSE4_1__) + extern const uint *QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); + extern const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_sse4; #endif + extern const uint *QT_FASTCALL convertARGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); + extern const uint *QT_FASTCALL convertRGBA8888FromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); + extern const uint *QT_FASTCALL convertRGBXFromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); qPixelLayouts[QImage::Format_ARGB32].convertFromARGB32PM = convertARGB32FromARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBA8888].convertFromARGB32PM = convertRGBA8888FromARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBX8888].convertFromARGB32PM = convertRGBXFromARGB32PM_sse4; } #endif +#if QT_COMPILER_SUPPORTS_AVX2 && !defined(__AVX2__) + if (qCpuHasFeature(AVX2)) { + extern const uint *QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); + extern const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); + qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_avx2; + qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_avx2; + } +#endif + functionForModeAsm = qt_functionForMode_SSE2; functionForModeSolidAsm = qt_functionForModeSolid_SSE2; #endif // SSE2 diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp new file mode 100644 index 0000000000..5716be682b --- /dev/null +++ b/src/gui/painting/qdrawhelper_avx2.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2015 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 <private/qdrawhelper_p.h> + +#if defined(QT_COMPILER_SUPPORTS_AVX2) + +QT_BEGIN_NAMESPACE + +const uint *QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + return qt_convertARGB32ToARGB32PM(buffer, src, count); +} + +const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + return qt_convertRGBA8888ToARGB32PM(buffer, src, count); +} + +QT_END_NAMESPACE + +#endif diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 08bc0776f7..480ba4c97b 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -769,7 +769,7 @@ do { \ do { \ /* Duff's device */ \ ushort *_d = (ushort*)(dest); \ - const ushort *_s = (ushort*)(src); \ + const ushort *_s = (const ushort*)(src); \ int n = ((length) + 7) / 8; \ switch ((length) & 0x07) \ { \ @@ -893,6 +893,22 @@ inline int qBlue565(quint16 rgb) { return (b << 3) | (b >> 2); } + +static Q_ALWAYS_INLINE const uint *qt_convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count) +{ + for (int i = 0; i < count; ++i) + buffer[i] = qPremultiply(src[i]); + return buffer; +} + +static Q_ALWAYS_INLINE const uint *qt_convertRGBA8888ToARGB32PM(uint *buffer, const uint *src, int count) +{ + for (int i = 0; i < count; ++i) + buffer[i] = qPremultiply(RGBA2ARGB(src[i])); + return buffer; +} + + const uint qt_bayer_matrix[16][16] = { { 0x1, 0xc0, 0x30, 0xf0, 0xc, 0xcc, 0x3c, 0xfc, 0x3, 0xc3, 0x33, 0xf3, 0xf, 0xcf, 0x3f, 0xff}, diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index 93d2d94626..84eb3b7909 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -111,7 +111,7 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, } for (; x < w-3; x += 4) { - __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); + __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[x]); if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVector, nullVector)) != 0xffff) { const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); __m128i result; @@ -162,7 +162,7 @@ void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uin // 2) composition with SSE2 for (; x < length - 3; x += 4) { - const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); + const __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[x]); const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); const __m128i result = _mm_adds_epu8(srcVector, dstVector); @@ -185,7 +185,7 @@ void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uin const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); // 2) composition with SSE2 for (; x < length - 3; x += 4) { - const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); + const __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[x]); const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); __m128i result = _mm_adds_epu8(srcVector, dstVector); @@ -218,7 +218,7 @@ void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, u const __m128i constAlphaVector = _mm_set1_epi16(const_alpha); const __m128i oneMinusConstAlpha = _mm_set1_epi16(ialpha); for (; x < length - 3; x += 4) { - const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); + const __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[x]); __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); INTERPOLATE_PIXEL_255_SSE2(dstVector, srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half) _mm_store_si128((__m128i *)&dst[x], dstVector); diff --git a/src/gui/painting/qdrawhelper_sse4.cpp b/src/gui/painting/qdrawhelper_sse4.cpp new file mode 100644 index 0000000000..43a3958997 --- /dev/null +++ b/src/gui/painting/qdrawhelper_sse4.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2015 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 <private/qdrawhelper_p.h> +#include <private/qdrawingprimitive_sse2_p.h> + +#if defined(QT_COMPILER_SUPPORTS_SSE4_1) + +QT_BEGIN_NAMESPACE + +const uint *QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + return qt_convertARGB32ToARGB32PM(buffer, src, count); +} + +const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + return qt_convertRGBA8888ToARGB32PM(buffer, src, count); +} + +const uint *QT_FASTCALL convertARGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = qUnpremultiply_sse4(src[i]); + return buffer; +} + +const uint *QT_FASTCALL convertRGBA8888FromARGB32PM_sse4(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = ARGB2RGBA(qUnpremultiply_sse4(src[i])); + return buffer; +} + +const uint *QT_FASTCALL convertRGBXFromARGB32PM_sse4(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = ARGB2RGBA(0xff000000 | qUnpremultiply_sse4(src[i])); + return buffer; +} + +QT_END_NAMESPACE + +#endif diff --git a/src/gui/painting/qdrawhelper_ssse3.cpp b/src/gui/painting/qdrawhelper_ssse3.cpp index cb4bd35d33..fff4145d21 100644 --- a/src/gui/painting/qdrawhelper_ssse3.cpp +++ b/src/gui/painting/qdrawhelper_ssse3.cpp @@ -53,7 +53,7 @@ inline static void blend_pixel(quint32 &dst, const quint32 src) */ #define BLENDING_LOOP(palignrOffset, length)\ for (; x-minusOffsetToAlignSrcOn16Bytes < length-7; x += 4) { \ - const __m128i srcVectorLastLoaded = _mm_load_si128((__m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes + 4]);\ + const __m128i srcVectorLastLoaded = _mm_load_si128((const __m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes + 4]);\ const __m128i srcVector = _mm_alignr_epi8(srcVectorLastLoaded, srcVectorPrevLoaded, palignrOffset); \ const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); \ if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { \ @@ -97,7 +97,7 @@ inline static void blend_pixel(quint32 &dst, const quint32 src) See the SSE2 version for more documentation on the algorithm itself. */\ const __m128i alphaShuffleMask = _mm_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);\ for (; x < length-3; x += 4) { \ - const __m128i srcVector = _mm_load_si128((__m128i *)&src[x]); \ + const __m128i srcVector = _mm_load_si128((const __m128i *)&src[x]); \ const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); \ if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { \ _mm_store_si128((__m128i *)&dst[x], srcVector); \ @@ -113,7 +113,7 @@ inline static void blend_pixel(quint32 &dst, const quint32 src) } /* end for() */\ } else if ((length - x) >= 8) {\ /* We use two vectors to extract the src: prevLoaded for the first pixels, lastLoaded for the current pixels. */\ - __m128i srcVectorPrevLoaded = _mm_load_si128((__m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes]);\ + __m128i srcVectorPrevLoaded = _mm_load_si128((const __m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes]);\ const int palignrOffset = minusOffsetToAlignSrcOn16Bytes << 2;\ \ const __m128i alphaShuffleMask = _mm_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);\ diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h index aded999cdd..4d0790a502 100644 --- a/src/gui/painting/qdrawingprimitive_sse2_p.h +++ b/src/gui/painting/qdrawingprimitive_sse2_p.h @@ -171,7 +171,7 @@ QT_BEGIN_NAMESPACE } \ \ for (; x < length-3; x += 4) { \ - const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); \ + const __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[x]); \ BLEND_SOURCE_OVER_ARGB32_SSE2_helper(dst, srcVector, nullVector, half, one, colorMask, alphaMask) \ } \ for (; x < length; ++x) { \ @@ -207,7 +207,7 @@ QT_BEGIN_NAMESPACE } \ \ for (; x < length-3; x += 4) { \ - __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); \ + __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[x]); \ if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVector, nullVector)) != 0xffff) { \ BYTE_MUL_SSE2(srcVector, srcVector, constAlphaVector, colorMask, half); \ \ diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp index 9ae95dff78..58e9112dd6 100644 --- a/src/gui/painting/qimagescale.cpp +++ b/src/gui/painting/qimagescale.cpp @@ -107,12 +107,12 @@ qt_qimageScaleFunc qt_qimageScaleRgb = qt_qimageScaleAARGB; namespace QImageScale { struct QImageScaleInfo { int *xpoints; - unsigned int **ypoints; + const unsigned int **ypoints; int *xapoints, *yapoints; int xup_yup; }; - unsigned int** qimageCalcYPoints(unsigned int *src, int sw, int sh, + const unsigned int** qimageCalcYPoints(const unsigned int *src, int sw, int sh, int dh); int* qimageCalcXPoints(int sw, int dw); int* qimageCalcApoints(int s, int d, int up); @@ -139,10 +139,10 @@ using namespace QImageScale; #define INV_YAP (256 - yapoints[dyy + y]) #define YAP (yapoints[dyy + y]) -unsigned int** QImageScale::qimageCalcYPoints(unsigned int *src, +const unsigned int** QImageScale::qimageCalcYPoints(const unsigned int *src, int sw, int sh, int dh) { - unsigned int **p; + const unsigned int **p; int i, j = 0, rv = 0; qint64 val, inc; @@ -150,7 +150,7 @@ unsigned int** QImageScale::qimageCalcYPoints(unsigned int *src, dh = -dh; rv = 1; } - p = new unsigned int* [dh+1]; + p = new const unsigned int* [dh+1]; int up = qAbs(dh) >= sh; val = up ? 0x8000 * sh / dh - 0x8000 : 0; @@ -161,7 +161,7 @@ unsigned int** QImageScale::qimageCalcYPoints(unsigned int *src, } if(rv){ for(i = dh / 2; --i >= 0; ){ - unsigned int *tmp = p[i]; + const unsigned int *tmp = p[i]; p[i] = p[dh - i - 1]; p[dh - i - 1] = tmp; } @@ -282,7 +282,7 @@ QImageScaleInfo* QImageScale::qimageCalcScaleInfo(const QImage &img, isi->xpoints = qimageCalcXPoints(img.width(), scw); if(!isi->xpoints) return(qimageFreeScaleInfo(isi)); - isi->ypoints = qimageCalcYPoints((unsigned int *)img.scanLine(0), + isi->ypoints = qimageCalcYPoints((const unsigned int *)img.scanLine(0), img.bytesPerLine() / 4, img.height(), sch); if (!isi->ypoints) return(qimageFreeScaleInfo(isi)); @@ -304,9 +304,10 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest, int dxx, int dyy, int dx, int dy, int dw, int dh, int dow, int sow) { - unsigned int *sptr, *dptr; + const unsigned int *sptr; + unsigned int *dptr; int x, y, end; - unsigned int **ypoints = isi->ypoints; + const unsigned int **ypoints = isi->ypoints; int *xpoints = isi->xpoints; int *xapoints = isi->xapoints; int *yapoints = isi->yapoints; @@ -323,7 +324,7 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest, for(x = dxx; x < end; x++){ int r, g, b, a; int rr, gg, bb, aa; - unsigned int *pix; + const unsigned int *pix; if(XAP > 0){ pix = ypoints[dyy + y] + xpoints[x]; @@ -374,7 +375,7 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest, else{ for(x = dxx; x < end; x++){ int r, g, b, a; - unsigned int *pix; + const unsigned int *pix; if(XAP > 0){ pix = ypoints[dyy + y] + xpoints[x]; @@ -403,7 +404,7 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest, else if(isi->xup_yup == 1){ /*\ 'Correct' version, with math units prepared for MMXification \*/ int Cy, j; - unsigned int *pix; + const unsigned int *pix; int r, g, b, a, rr, gg, bb, aa; int yap; @@ -477,7 +478,7 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest, else if(isi->xup_yup == 2){ /*\ 'Correct' version, with math units prepared for MMXification \*/ int Cx, j; - unsigned int *pix; + const unsigned int *pix; int r, g, b, a, rr, gg, bb, aa; int xap; @@ -555,7 +556,7 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest, |*| psllw (16 - d), %mmb; pmulh %mmc, %mmb \*/ int Cx, Cy, i, j; - unsigned int *pix; + const unsigned int *pix; int a, r, g, b, ax, rx, gx, bx; int xap, yap; @@ -663,9 +664,10 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest, int dxx, int dyy, int dx, int dy, int dw, int dh, int dow, int sow) { - unsigned int *sptr, *dptr; + const unsigned int *sptr; + unsigned int *dptr; int x, y, end; - unsigned int **ypoints = isi->ypoints; + const unsigned int **ypoints = isi->ypoints; int *xpoints = isi->xpoints; int *xapoints = isi->xapoints; int *yapoints = isi->yapoints; @@ -682,7 +684,7 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest, for(x = dxx; x < end; x++){ int r = 0, g = 0, b = 0; int rr = 0, gg = 0, bb = 0; - unsigned int *pix; + const unsigned int *pix; if(XAP > 0){ pix = ypoints[dyy + y] + xpoints[x]; @@ -725,7 +727,7 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest, else{ for(x = dxx; x < end; x++){ int r = 0, g = 0, b = 0; - unsigned int *pix; + const unsigned int *pix; if(XAP > 0){ pix = ypoints[dyy + y] + xpoints[x]; @@ -751,7 +753,7 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest, else if(isi->xup_yup == 1){ /*\ 'Correct' version, with math units prepared for MMXification \*/ int Cy, j; - unsigned int *pix; + const unsigned int *pix; int r, g, b, rr, gg, bb; int yap; @@ -816,7 +818,7 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest, else if(isi->xup_yup == 2){ /*\ 'Correct' version, with math units prepared for MMXification \*/ int Cx, j; - unsigned int *pix; + const unsigned int *pix; int r, g, b, rr, gg, bb; int xap; @@ -882,7 +884,7 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest, else{ /*\ 'Correct' version, with math units prepared for MMXification \*/ int Cx, Cy, i, j; - unsigned int *pix; + const unsigned int *pix; int r, g, b, rx, gx, bx; int xap, yap; diff --git a/src/gui/painting/qpaintengine_blitter.cpp b/src/gui/painting/qpaintengine_blitter.cpp index 7c33dbe266..a2bab58922 100644 --- a/src/gui/painting/qpaintengine_blitter.cpp +++ b/src/gui/painting/qpaintengine_blitter.cpp @@ -531,7 +531,7 @@ void QBlitterPaintEngine::fill(const QVectorPath &path, const QBrush &brush) { Q_D(QBlitterPaintEngine); if (path.shape() == QVectorPath::RectangleHint) { - QRectF rect(((QPointF *) path.points())[0], ((QPointF *) path.points())[2]); + QRectF rect(((const QPointF *) path.points())[0], ((const QPointF *) path.points())[2]); fillRect(rect, brush); } else { d->lock(); diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 1a1f63844c..18522cb6d0 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1864,7 +1864,7 @@ void QRasterPaintEngine::fillPolygon(const QPointF *points, int pointCount, Poly } // Compose polygon fill.., - QVectorPath vp((qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode)); + QVectorPath vp((const qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode)); ensureOutlineMapper(); QT_FT_Outline *outline = d->outlineMapper->convertPath(vp); @@ -1889,7 +1889,7 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly #endif Q_ASSERT(pointCount >= 2); - if (mode != PolylineMode && QVectorPath::isRect((qreal *) points, pointCount)) { + if (mode != PolylineMode && QVectorPath::isRect((const qreal *) points, pointCount)) { QRectF r(points[0], points[2]); drawRects(&r, 1); return; @@ -1905,7 +1905,7 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly // Do the outline... if (s->penData.blend) { - QVectorPath vp((qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode)); + QVectorPath vp((const qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode)); if (s->flags.fast_pen) { QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped); stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding); @@ -1930,7 +1930,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg qDebug() << " - " << points[i]; #endif Q_ASSERT(pointCount >= 2); - if (mode != PolylineMode && QVectorPath::isRect((int *) points, pointCount)) { + if (mode != PolylineMode && QVectorPath::isRect((const int *) points, pointCount)) { QRect r(points[0].x(), points[0].y(), points[2].x() - points[0].x(), @@ -1968,7 +1968,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg int count = pointCount * 2; QVarLengthArray<qreal> fpoints(count); for (int i=0; i<count; ++i) - fpoints[i] = ((int *) points)[i]; + fpoints[i] = ((const int *) points)[i]; QVectorPath vp((qreal *) fpoints.data(), pointCount, 0, QVectorPath::polygonFlags(mode)); if (s->flags.fast_pen) { @@ -2695,7 +2695,7 @@ void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx scanline += bpl; } } else { // 32-bit alpha... - uint *sl = (uint *) scanline; + const uint *sl = (const uint *) scanline; for (int y = y0; y < y1; ++y) { for (int x = x0; x < x1; ) { // Skip those with 0 coverage diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 1de821e1c4..0f80cd18a0 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -521,23 +521,23 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) while (points < lastPoint) { switch (*types) { case QPainterPath::MoveToElement: { - QPointF pt = (*(QPointF *) points) * state()->matrix; + QPointF pt = (*(const QPointF *) points) * state()->matrix; d->activeStroker->moveTo(pt.x(), pt.y()); points += 2; ++types; break; } case QPainterPath::LineToElement: { - QPointF pt = (*(QPointF *) points) * state()->matrix; + QPointF pt = (*(const QPointF *) points) * state()->matrix; d->activeStroker->lineTo(pt.x(), pt.y()); points += 2; ++types; break; } case QPainterPath::CurveToElement: { - QPointF c1 = ((QPointF *) points)[0] * state()->matrix; - QPointF c2 = ((QPointF *) points)[1] * state()->matrix; - QPointF e = ((QPointF *) points)[2] * state()->matrix; + QPointF c1 = ((const QPointF *) points)[0] * state()->matrix; + QPointF c2 = ((const QPointF *) points)[1] * state()->matrix; + QPointF e = ((const QPointF *) points)[2] * state()->matrix; d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y()); points += 6; types += 3; @@ -549,16 +549,16 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) } } if (path.hasImplicitClose()) { - QPointF pt = * ((QPointF *) path.points()) * state()->matrix; + QPointF pt = * ((const QPointF *) path.points()) * state()->matrix; d->activeStroker->lineTo(pt.x(), pt.y()); } } else { - QPointF p = ((QPointF *)points)[0] * state()->matrix; + QPointF p = ((const QPointF *)points)[0] * state()->matrix; d->activeStroker->moveTo(p.x(), p.y()); points += 2; while (points < lastPoint) { - QPointF p = ((QPointF *)points)[0] * state()->matrix; + QPointF p = ((const QPointF *)points)[0] * state()->matrix; d->activeStroker->lineTo(p.x(), p.y()); points += 2; } @@ -786,7 +786,7 @@ void QPaintEngineEx::drawLines(const QLine *lines, int lineCount) qreal pts[64]; int count2 = count<<1; for (int i=0; i<count2; ++i) - pts[i] = ((int *) lines)[i]; + pts[i] = ((const int *) lines)[i]; QVectorPath path(pts, count, qpaintengineex_line_types_16, QVectorPath::LinesHint); stroke(path, state()->pen); @@ -802,7 +802,7 @@ void QPaintEngineEx::drawLines(const QLineF *lines, int lineCount) while (elementCount > 0) { int count = qMin(elementCount, 32); - QVectorPath path((qreal *) lines, count, qpaintengineex_line_types_16, + QVectorPath path((const qreal *) lines, count, qpaintengineex_line_types_16, QVectorPath::LinesHint); stroke(path, state()->pen); @@ -906,7 +906,7 @@ void QPaintEngineEx::drawPoints(const QPoint *points, int pointCount) void QPaintEngineEx::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) { - QVectorPath path((qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode)); + QVectorPath path((const qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode)); if (mode == PolylineMode) stroke(path, state()->pen); @@ -920,7 +920,7 @@ void QPaintEngineEx::drawPolygon(const QPoint *points, int pointCount, PolygonDr QVarLengthArray<qreal> pts(count); for (int i=0; i<count; ++i) - pts[i] = ((int *) points)[i]; + pts[i] = ((const int *) points)[i]; QVectorPath path(pts.data(), pointCount, 0, QVectorPath::polygonFlags(mode)); diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index bdbb49ff51..6f00abfc5f 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -4626,7 +4626,7 @@ void QPainter::drawLines(const QPointF *pointPairs, int lineCount) { Q_ASSERT(sizeof(QLineF) == 2*sizeof(QPointF)); - drawLines((QLineF*)pointPairs, lineCount); + drawLines((const QLineF*)pointPairs, lineCount); } /*! @@ -4639,7 +4639,7 @@ void QPainter::drawLines(const QPoint *pointPairs, int lineCount) { Q_ASSERT(sizeof(QLine) == 2*sizeof(QPoint)); - drawLines((QLine*)pointPairs, lineCount); + drawLines((const QLine*)pointPairs, lineCount); } @@ -5565,22 +5565,19 @@ void QPainter::drawGlyphRun(const QPointF &position, const QGlyphRun &glyphRun) fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition); } - d->drawGlyphs(glyphIndexes, fixedPointPositions.data(), count, font, glyphRun.overline(), - glyphRun.underline(), glyphRun.strikeOut()); + d->drawGlyphs(glyphIndexes, fixedPointPositions.data(), count, fontD->fontEngine, + glyphRun.overline(), glyphRun.underline(), glyphRun.strikeOut()); } void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, QFixedPoint *positions, int glyphCount, - const QRawFont &font, bool overline, bool underline, + QFontEngine *fontEngine, bool overline, bool underline, bool strikeOut) { Q_Q(QPainter); updateState(state); - QRawFontPrivate *fontD = QRawFontPrivate::get(font); - QFontEngine *fontEngine = fontD->fontEngine; - QFixed leftMost; QFixed rightMost; QFixed baseLine; diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h index dde01d32fa..7c32dc1694 100644 --- a/src/gui/painting/qpainter_p.h +++ b/src/gui/painting/qpainter_p.h @@ -70,7 +70,7 @@ struct DataPtrContainer { void *ptr; }; -inline void *data_ptr(const QTransform &t) { return (DataPtrContainer *) &t; } +inline const void *data_ptr(const QTransform &t) { return (const DataPtrContainer *) &t; } inline bool qtransform_fast_equals(const QTransform &a, const QTransform &b) { return data_ptr(a) == data_ptr(b); } // QPen inline functions... @@ -226,7 +226,7 @@ public: #if !defined(QT_NO_RAWFONT) void drawGlyphs(const quint32 *glyphArray, QFixedPoint *positionArray, int glyphCount, - const QRawFont &font, bool overline = false, bool underline = false, + QFontEngine *fontEngine, bool overline = false, bool underline = false, bool strikeOut = false); #endif diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 6834222f08..b028d868b9 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1622,7 +1622,8 @@ void QFontEngineMulti::setFallbackFamiliesList(const QStringList &fallbackFamili void QFontEngineMulti::ensureEngineAt(int at) { - Q_ASSERT(m_fallbackFamiliesQueried); + if (!m_fallbackFamiliesQueried) + ensureFallbackFamiliesQueried(); Q_ASSERT(at < m_engines.size()); if (!m_engines.at(at)) { QFontEngine *engine = loadEngine(at); diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index b79f971156..8ae178c6ad 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -891,8 +891,6 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, FT_Matrix_Multiply(&m, &matrix); } - FT_Library library = qt_getFreetype(); - info.xOff = TRUNC(ROUND(slot->advance.x)); info.yOff = 0; @@ -930,12 +928,12 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, return g; } - uchar *glyph_buffer = 0; int glyph_buffer_size = 0; + QScopedArrayPointer<uchar> glyph_buffer; #if defined(QT_USE_FREETYPE_LCDFILTER) bool useFreetypeRenderGlyph = false; if (slot->format == FT_GLYPH_FORMAT_OUTLINE && (hsubpixel || vfactor != 1)) { - err = FT_Library_SetLcdFilter(library, (FT_LcdFilter)lcdFilterType); + err = FT_Library_SetLcdFilter(slot->library, (FT_LcdFilter)lcdFilterType); if (err == FT_Err_Ok) useFreetypeRenderGlyph = true; } @@ -946,7 +944,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, if (err != FT_Err_Ok) qWarning("render glyph failed err=%x face=%p, glyph=%d", err, face, glyph); - FT_Library_SetLcdFilter(library, FT_LCD_FILTER_NONE); + FT_Library_SetLcdFilter(slot->library, FT_LCD_FILTER_NONE); info.height = slot->bitmap.rows / vfactor; info.width = hsubpixel ? slot->bitmap.width / 3 : slot->bitmap.width; @@ -954,12 +952,12 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, info.y = slot->bitmap_top; glyph_buffer_size = info.width * info.height * 4; - glyph_buffer = new uchar[glyph_buffer_size]; + glyph_buffer.reset(new uchar[glyph_buffer_size]); if (hsubpixel) - convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_RGB, false); + convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_RGB, false); else if (vfactor != 1) - convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB, false); + convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB, false); } else #endif { @@ -1030,26 +1028,30 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, || ((signed char)(info.xOff) != info.xOff)); if (large_glyph) { - delete [] glyph_buffer; return 0; } int pitch = (format == Format_Mono ? ((info.width + 31) & ~31) >> 3 : (format == Format_A8 ? (info.width + 3) & ~3 : info.width * 4)); - glyph_buffer_size = pitch * info.height; - glyph_buffer = new uchar[glyph_buffer_size]; - memset(glyph_buffer, 0, glyph_buffer_size); + if (glyph_buffer_size < pitch * info.height) { + glyph_buffer_size = pitch * info.height; + glyph_buffer.reset(new uchar[glyph_buffer_size]); + } + memset(glyph_buffer.data(), 0, glyph_buffer_size); if (slot->format == FT_GLYPH_FORMAT_OUTLINE) { FT_Bitmap bitmap; bitmap.rows = info.height*vfactor; bitmap.width = hpixels; bitmap.pitch = format == Format_Mono ? (((info.width + 31) & ~31) >> 3) : ((bitmap.width + 3) & ~3); - if (!hsubpixel && vfactor == 1 && format != Format_A32) - bitmap.buffer = glyph_buffer; - else - bitmap.buffer = new uchar[bitmap.rows*bitmap.pitch]; - memset(bitmap.buffer, 0, bitmap.rows*bitmap.pitch); + int bitmap_buffer_size = bitmap.rows * bitmap.pitch; + if (!hsubpixel && vfactor == 1 && format != Format_A32) { + Q_ASSERT(glyph_buffer_size <= bitmap_buffer_size); + bitmap.buffer = glyph_buffer.data(); + } else { + bitmap.buffer = new uchar[bitmap_buffer_size]; + memset(bitmap.buffer, 0, bitmap_buffer_size); + } bitmap.pixel_mode = format == Format_Mono ? FT_PIXEL_MODE_MONO : FT_PIXEL_MODE_GRAY; FT_Matrix matrix; matrix.xx = (hsubpixel ? 3 : 1) << 16; @@ -1058,11 +1060,11 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, FT_Outline_Transform(&slot->outline, &matrix); FT_Outline_Translate (&slot->outline, (hsubpixel ? -3*left +(4<<6) : -left), -bottom*vfactor); - FT_Outline_Get_Bitmap(library, &slot->outline, &bitmap); + FT_Outline_Get_Bitmap(slot->library, &slot->outline, &bitmap); if (hsubpixel) { Q_ASSERT (bitmap.pixel_mode == FT_PIXEL_MODE_GRAY); Q_ASSERT(antialias); - uchar *convoluted = new uchar[bitmap.rows*bitmap.pitch]; + uchar *convoluted = new uchar[bitmap_buffer_size]; bool useLegacyLcdFilter = false; #if defined(FC_LCD_FILTER) && defined(FT_LCD_FILTER_H) useLegacyLcdFilter = (lcdFilterType == FT_LCD_FILTER_LEGACY); @@ -1072,20 +1074,20 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, convoluteBitmap(bitmap.buffer, convoluted, bitmap.width, info.height, bitmap.pitch); buffer = convoluted; } - convertRGBToARGB(buffer + 1, (uint *)glyph_buffer, info.width, info.height, bitmap.pitch, subpixelType != Subpixel_RGB, useLegacyLcdFilter); + convertRGBToARGB(buffer + 1, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch, subpixelType != Subpixel_RGB, useLegacyLcdFilter); delete [] convoluted; } else if (vfactor != 1) { - convertRGBToARGB_V(bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, bitmap.pitch, subpixelType != Subpixel_VRGB, true); + convertRGBToARGB_V(bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch, subpixelType != Subpixel_VRGB, true); } else if (format == Format_A32 && bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) { - convertGRAYToARGB(bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, bitmap.pitch); + convertGRAYToARGB(bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch); } - if (bitmap.buffer != glyph_buffer) + if (bitmap.buffer != glyph_buffer.data()) delete [] bitmap.buffer; } else if (slot->format == FT_GLYPH_FORMAT_BITMAP) { Q_ASSERT(slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO); uchar *src = slot->bitmap.buffer; - uchar *dst = glyph_buffer; + uchar *dst = glyph_buffer.data(); int h = slot->bitmap.rows; if (format == Format_Mono) { int bytes = ((info.width + 7) & ~7) >> 3; @@ -1130,7 +1132,6 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, } } else { qWarning("QFontEngine: Glyph neither outline nor bitmap format=%d", slot->format); - delete [] glyph_buffer; return 0; } } @@ -1149,7 +1150,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, g->advance = info.xOff; g->format = format; delete [] g->data; - g->data = glyph_buffer; + g->data = glyph_buffer.take(); if (set) set->setGlyph(glyph, subPixelPosition, g); @@ -1333,14 +1334,14 @@ static inline FT_Matrix QTransformToFTMatrix(const QTransform &matrix) return m; } -QFontEngineFT::QGlyphSet *QFontEngineFT::loadTransformedGlyphSet(const QTransform &matrix) +QFontEngineFT::QGlyphSet *QFontEngineFT::loadGlyphSet(const QTransform &matrix) { if (matrix.type() > QTransform::TxShear || !cacheEnabled) return 0; // FT_Set_Transform only supports scalable fonts if (!FT_IS_SCALABLE(freetype->face)) - return 0; + return matrix.type() <= QTransform::TxTranslate ? &defaultGlyphSet : Q_NULLPTR; FT_Matrix m = QTransformToFTMatrix(matrix); @@ -1757,15 +1758,11 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe QFontEngineFT::Glyph *glyph; QScopedPointer<QFontEngineFT::Glyph> glyphGuard; if (cacheEnabled) { - QFontEngineFT::QGlyphSet *gset = &defaultGlyphSet; + QGlyphSet *gset = loadGlyphSet(t); QFontEngine::HintStyle hintStyle = default_hint_style; if (t.type() >= QTransform::TxScale) { // disable hinting if the glyphs are transformed default_hint_style = HintNone; - if (t.isAffine()) - gset = loadTransformedGlyphSet(t); - else - gset = 0; } if (gset) { @@ -1842,31 +1839,20 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, const QTransform &t, bool fetchBoundingBox) { - FT_Face face = 0; - QGlyphSet *glyphSet = 0; - FT_Matrix ftMatrix = QTransformToFTMatrix(t); - if (cacheEnabled) { - if (t.type() > QTransform::TxTranslate && FT_IS_SCALABLE(freetype->face)) - glyphSet = loadTransformedGlyphSet(t); - else - glyphSet = &defaultGlyphSet; - Q_ASSERT(glyphSet != 0); - } - + QGlyphSet *glyphSet = loadGlyphSet(t); if (glyphSet != 0 && glyphSet->outline_drawing && !fetchBoundingBox) return 0; Glyph *glyph = glyphSet != 0 ? glyphSet->getGlyph(g, subPixelPosition) : 0; - if (!glyph || glyph->format != format) { - face = lockFace(); + if (!glyph || glyph->format != format || (!fetchBoundingBox && !glyph->data)) { + lockFace(); FT_Matrix m = this->matrix; + FT_Matrix ftMatrix = glyphSet != 0 ? glyphSet->transformationMatrix : QTransformToFTMatrix(t); FT_Matrix_Multiply(&ftMatrix, &m); freetype->matrix = m; glyph = loadGlyph(glyphSet, g, subPixelPosition, format, false); - } - - if (face) unlockFace(); + } return glyph; } diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 1218893e19..e9d058d50c 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -268,7 +268,7 @@ private: Glyph *loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat = Format_None, bool fetchMetricsOnly = false) const; Glyph *loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format, const QTransform &t, bool fetchBoundingBox = false); - QGlyphSet *loadTransformedGlyphSet(const QTransform &matrix); + QGlyphSet *loadGlyphSet(const QTransform &matrix); QFontEngineFT(const QFontDef &fd); virtual ~QFontEngineFT(); diff --git a/src/gui/text/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp index 24dda422fc..9f652084be 100644 --- a/src/gui/text/qfontsubset.cpp +++ b/src/gui/text/qfontsubset.cpp @@ -420,7 +420,7 @@ static quint32 checksum(const QByteArray &table) { quint32 sum = 0; int offset = 0; - const uchar *d = (uchar *)table.constData(); + const uchar *d = (const uchar *)table.constData(); while (offset <= table.size()-3) { sum += qFromBigEndian<quint32>(d + offset); offset += 4; diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp index 321c7937f7..9f561dcb02 100644 --- a/src/gui/text/qzip.cpp +++ b/src/gui/text/qzip.cpp @@ -194,7 +194,7 @@ static int inflate(Bytef *dest, ulong *destLen, const Bytef *source, ulong sourc z_stream stream; int err; - stream.next_in = (Bytef*)source; + stream.next_in = const_cast<Bytef*>(source); stream.avail_in = (uInt)sourceLen; if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; @@ -229,7 +229,7 @@ static int deflate (Bytef *dest, ulong *destLen, const Bytef *source, ulong sour z_stream stream; int err; - stream.next_in = (Bytef*)source; + stream.next_in = const_cast<Bytef*>(source); stream.avail_in = (uInt)sourceLen; stream.next_out = dest; stream.avail_out = (uInt)*destLen; @@ -1008,7 +1008,7 @@ QByteArray QZipReader::fileData(const QString &fileName) const do { baunzip.resize(len); res = inflate((uchar*)baunzip.data(), &len, - (uchar*)compressed.constData(), compressed_size); + (const uchar*)compressed.constData(), compressed_size); switch (res) { case Z_OK: diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index 091129f5be..61e239f678 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -86,7 +86,7 @@ HEADERS += \ contains(QT_CONFIG, harfbuzz)|contains(QT_CONFIG, system-harfbuzz) { DEFINES += QT_ENABLE_HARFBUZZ_NG - include($$PWD/../../3rdparty/harfbuzzng.pri) + include($$PWD/../../3rdparty/harfbuzz_dependency.pri) SOURCES += text/qharfbuzzng.cpp HEADERS += text/qharfbuzzng_p.h diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index 9a993392e9..58c0de1f3b 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -415,6 +415,19 @@ QHostAddress::QHostAddress(quint8 *ip6Addr) } /*! + \since 5.5 + Constructs a host address object with the IPv6 address \a ip6Addr. + + \a ip6Addr must be a 16-byte array in network byte order (big + endian). +*/ +QHostAddress::QHostAddress(const quint8 *ip6Addr) + : d(new QHostAddressPrivate) +{ + setAddress(ip6Addr); +} + +/*! Constructs a host address object with the IPv6 address \a ip6Addr. */ QHostAddress::QHostAddress(const Q_IPV6ADDR &ip6Addr) @@ -449,9 +462,9 @@ QHostAddress::QHostAddress(const struct sockaddr *sockaddr) { #ifndef Q_OS_WINRT if (sockaddr->sa_family == AF_INET) - setAddress(htonl(((sockaddr_in *)sockaddr)->sin_addr.s_addr)); + setAddress(htonl(((const sockaddr_in *)sockaddr)->sin_addr.s_addr)); else if (sockaddr->sa_family == AF_INET6) - setAddress(((qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr); + setAddress(((const qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr); #else Q_UNUSED(sockaddr) #endif @@ -575,6 +588,20 @@ void QHostAddress::setAddress(quint8 *ip6Addr) /*! \overload + \since 5.5 + + Set the IPv6 address specified by \a ip6Addr. + + \a ip6Addr must be an array of 16 bytes in network byte order + (high-order byte first). +*/ +void QHostAddress::setAddress(const quint8 *ip6Addr) +{ + d->setAddress(ip6Addr); +} + +/*! + \overload Set the IPv6 address specified by \a ip6Addr. */ @@ -610,9 +637,9 @@ void QHostAddress::setAddress(const struct sockaddr *sockaddr) #ifndef Q_OS_WINRT clear(); if (sockaddr->sa_family == AF_INET) - setAddress(htonl(((sockaddr_in *)sockaddr)->sin_addr.s_addr)); + setAddress(htonl(((const sockaddr_in *)sockaddr)->sin_addr.s_addr)); else if (sockaddr->sa_family == AF_INET6) - setAddress(((qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr); + setAddress(((const qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr); #else Q_UNUSED(sockaddr) #endif diff --git a/src/network/kernel/qhostaddress.h b/src/network/kernel/qhostaddress.h index de3a79278e..0c2229c334 100644 --- a/src/network/kernel/qhostaddress.h +++ b/src/network/kernel/qhostaddress.h @@ -75,7 +75,8 @@ public: QHostAddress(); explicit QHostAddress(quint32 ip4Addr); - explicit QHostAddress(quint8 *ip6Addr); + explicit QHostAddress(quint8 *ip6Addr); // ### Qt 6: remove me + explicit QHostAddress(const quint8 *ip6Addr); explicit QHostAddress(const Q_IPV6ADDR &ip6Addr); explicit QHostAddress(const sockaddr *address); explicit QHostAddress(const QString &address); @@ -87,7 +88,8 @@ public: QHostAddress &operator=(const QString &address); void setAddress(quint32 ip4Addr); - void setAddress(quint8 *ip6Addr); + void setAddress(quint8 *ip6Addr); // ### Qt 6: remove me + void setAddress(const quint8 *ip6Addr); void setAddress(const Q_IPV6ADDR &ip6Addr); void setAddress(const sockaddr *address); bool setAddress(const QString &address); diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp index 165d4eff7d..9c5ba4e799 100644 --- a/src/network/kernel/qnetworkinterface_unix.cpp +++ b/src/network/kernel/qnetworkinterface_unix.cpp @@ -100,7 +100,7 @@ static QHostAddress addressFromSockaddr(sockaddr *sa, int ifindex = 0, const QSt address.setScopeId(QLatin1String(scopeid)); } else #endif - address.setScopeId(QString::number(scope)); + address.setScopeId(QString::number(uint(scope))); } } return address; diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index da36e4a6da..4648a3cb5a 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Intel Corporation. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtNetwork module of the Qt Toolkit. @@ -127,6 +128,83 @@ static inline void qt_socket_getPortAndAddress(const qt_sockaddr *s, quint16 *po } } +static inline uint makeScopeId(const QHostAddress &addr) +{ + QString scopeid = addr.scopeId(); + if (scopeid.isEmpty()) + return 0; + + bool ok; + uint id = scopeid.toUInt(&ok); +#ifndef QT_NO_IPV6IFNAME + if (!ok) + id = ::if_nametoindex(scopeid.toLatin1()); +#endif + return id; +} + +static void convertToLevelAndOption(QNativeSocketEngine::SocketOption opt, + QAbstractSocket::NetworkLayerProtocol socketProtocol, int &level, int &n) +{ + n = -1; + level = SOL_SOCKET; // default + + switch (opt) { + case QNativeSocketEngine::NonBlockingSocketOption: // fcntl, not setsockopt + case QNativeSocketEngine::BindExclusively: // not handled on Unix + Q_UNREACHABLE(); + + case QNativeSocketEngine::BroadcastSocketOption: + n = SO_BROADCAST; + break; + case QNativeSocketEngine::ReceiveBufferSocketOption: + n = SO_RCVBUF; + break; + case QNativeSocketEngine::SendBufferSocketOption: + n = SO_SNDBUF; + break; + case QNativeSocketEngine::AddressReusable: + n = SO_REUSEADDR; + break; + case QNativeSocketEngine::ReceiveOutOfBandData: + n = SO_OOBINLINE; + break; + case QNativeSocketEngine::LowDelayOption: + level = IPPROTO_TCP; + n = TCP_NODELAY; + break; + case QNativeSocketEngine::KeepAliveOption: + n = SO_KEEPALIVE; + break; + case QNativeSocketEngine::MulticastTtlOption: + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { + level = IPPROTO_IPV6; + n = IPV6_MULTICAST_HOPS; + } else + { + level = IPPROTO_IP; + n = IP_MULTICAST_TTL; + } + break; + case QNativeSocketEngine::MulticastLoopbackOption: + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { + level = IPPROTO_IPV6; + n = IPV6_MULTICAST_LOOP; + } else + { + level = IPPROTO_IP; + n = IP_MULTICAST_LOOP; + } + break; + case QNativeSocketEngine::TypeOfServiceOption: + if (socketProtocol == QAbstractSocket::IPv4Protocol) { + level = IPPROTO_IP; + n = IP_TOS; + } + break; + } +} + /*! \internal Creates and returns a new socket descriptor of type \a socketType @@ -193,65 +271,16 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co if (!q->isValid()) return -1; - int n = -1; - int level = SOL_SOCKET; // default - - switch (opt) { - case QNativeSocketEngine::ReceiveBufferSocketOption: - n = SO_RCVBUF; - break; - case QNativeSocketEngine::SendBufferSocketOption: - n = SO_SNDBUF; - break; - case QNativeSocketEngine::NonBlockingSocketOption: - break; - case QNativeSocketEngine::BroadcastSocketOption: - break; - case QNativeSocketEngine::AddressReusable: - n = SO_REUSEADDR; - break; - case QNativeSocketEngine::BindExclusively: + // handle non-getsockopt cases first + if (opt == QNativeSocketEngine::BindExclusively || opt == QNativeSocketEngine::NonBlockingSocketOption + || opt == QNativeSocketEngine::BroadcastSocketOption) return true; - case QNativeSocketEngine::ReceiveOutOfBandData: - n = SO_OOBINLINE; - break; - case QNativeSocketEngine::LowDelayOption: - level = IPPROTO_TCP; - n = TCP_NODELAY; - break; - case QNativeSocketEngine::KeepAliveOption: - n = SO_KEEPALIVE; - break; - case QNativeSocketEngine::MulticastTtlOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_HOPS; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_TTL; - } - break; - case QNativeSocketEngine::MulticastLoopbackOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_LOOP; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_LOOP; - } - break; - case QNativeSocketEngine::TypeOfServiceOption: - if (socketProtocol == QAbstractSocket::IPv4Protocol) { - level = IPPROTO_IP; - n = IP_TOS; - } - break; - } + int n, level; int v = -1; QT_SOCKOPTLEN_T len = sizeof(v); + + convertToLevelAndOption(opt, socketProtocol, level, n); if (::getsockopt(socketDescriptor, level, n, (char *) &v, &len) != -1) return v; @@ -268,19 +297,8 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt if (!q->isValid()) return false; - int n = 0; - int level = SOL_SOCKET; // default - + // handle non-setsockopt cases first switch (opt) { - case QNativeSocketEngine::ReceiveBufferSocketOption: - n = SO_RCVBUF; - break; - case QNativeSocketEngine::SendBufferSocketOption: - n = SO_SNDBUF; - break; - case QNativeSocketEngine::BroadcastSocketOption: - n = SO_BROADCAST; - break; case QNativeSocketEngine::NonBlockingSocketOption: { // Make the socket nonblocking. #if !defined(Q_OS_VXWORKS) @@ -310,58 +328,24 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt #endif // Q_OS_VXWORKS return true; } - case QNativeSocketEngine::AddressReusable: + case QNativeSocketEngine::BindExclusively: + return true; + + default: + break; + } + + int n, level; + convertToLevelAndOption(opt, socketProtocol, level, n); #if defined(SO_REUSEPORT) + if (opt == QNativeSocketEngine::AddressReusable) { // on OS X, SO_REUSEADDR isn't sufficient to allow multiple binds to the // same port (which is useful for multicast UDP). SO_REUSEPORT is, but // we most definitely do not want to use this for TCP. See QTBUG-6305. if (socketType == QAbstractSocket::UdpSocket) n = SO_REUSEPORT; - else - n = SO_REUSEADDR; -#else - n = SO_REUSEADDR; -#endif - break; - case QNativeSocketEngine::BindExclusively: - return true; - case QNativeSocketEngine::ReceiveOutOfBandData: - n = SO_OOBINLINE; - break; - case QNativeSocketEngine::LowDelayOption: - level = IPPROTO_TCP; - n = TCP_NODELAY; - break; - case QNativeSocketEngine::KeepAliveOption: - n = SO_KEEPALIVE; - break; - case QNativeSocketEngine::MulticastTtlOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_HOPS; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_TTL; - } - break; - case QNativeSocketEngine::MulticastLoopbackOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_LOOP; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_LOOP; - } - break; - case QNativeSocketEngine::TypeOfServiceOption: - if (socketProtocol == QAbstractSocket::IPv4Protocol) { - level = IPPROTO_IP; - n = IP_TOS; - } - break; } +#endif return ::setsockopt(socketDescriptor, level, n, (char *) &v, sizeof(v)) == 0; } @@ -382,17 +366,8 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6)); sockAddrIPv6.sin6_family = AF_INET6; sockAddrIPv6.sin6_port = htons(port); + sockAddrIPv6.sin6_scope_id = makeScopeId(addr); - QString scopeid = addr.scopeId(); - - if (!scopeid.isEmpty()) { - bool ok; - sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok); -#ifndef QT_NO_IPV6IFNAME - if (!ok) - sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1()); -#endif - } Q_IPV6ADDR ip6 = addr.toIPv6Address(); memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &ip6, sizeof(ip6)); @@ -501,16 +476,8 @@ bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16 memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6)); sockAddrIPv6.sin6_family = AF_INET6; sockAddrIPv6.sin6_port = htons(port); - QString scopeid = address.scopeId(); + sockAddrIPv6.sin6_scope_id = makeScopeId(address); - if (!scopeid.isEmpty()) { - bool ok; - sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok); -#ifndef QT_NO_IPV6IFNAME - if (!ok) - sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1()); -#endif - } Q_IPV6ADDR tmp = address.toIPv6Address(); memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp)); sockAddrSize = sizeof(sockAddrIPv6); @@ -749,7 +716,7 @@ bool QNativeSocketEnginePrivate::nativeLeaveMulticastGroup(const QHostAddress &g QNetworkInterface QNativeSocketEnginePrivate::nativeMulticastInterface() const { - if (socketProtocol == QAbstractSocket::IPv6Protocol) { + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { uint v; QT_SOCKOPTLEN_T sizeofv = sizeof(v); if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, &v, &sizeofv) == -1) @@ -779,7 +746,7 @@ QNetworkInterface QNativeSocketEnginePrivate::nativeMulticastInterface() const bool QNativeSocketEnginePrivate::nativeSetMulticastInterface(const QNetworkInterface &iface) { - if (socketProtocol == QAbstractSocket::IPv6Protocol) { + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { uint v = iface.index(); return (::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, &v, sizeof(v)) != -1); } @@ -918,19 +885,10 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6)); sockAddrIPv6.sin6_family = AF_INET6; sockAddrIPv6.sin6_port = htons(port); + sockAddrIPv6.sin6_scope_id = makeScopeId(host); Q_IPV6ADDR tmp = host.toIPv6Address(); memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp)); - QString scopeid = host.scopeId(); - - if (!scopeid.isEmpty()) { - bool ok; - sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok); -#ifndef QT_NO_IPV6IFNAME - if (!ok) - sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1()); -#endif - } sockAddrSize = sizeof(sockAddrIPv6); sockAddrPtr = (struct sockaddr *)&sockAddrIPv6; } else if (host.protocol() == QAbstractSocket::IPv4Protocol) { @@ -1037,7 +995,7 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() #if defined (QNATIVESOCKETENGINE_DEBUG) QString socketProtocolStr = QStringLiteral("UnknownProtocol"); if (socketProtocol == QAbstractSocket::IPv4Protocol) socketProtocolStr = QStringLiteral("IPv4Protocol"); - else if (socketProtocol == QAbstractSocket::IPv6Protocol) socketProtocolStr = QStringLiteral("IPv6Protocol"); + else if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) socketProtocolStr = QStringLiteral("IPv6Protocol"); QString socketTypeStr = QStringLiteral("UnknownSocketType"); if (socketType == QAbstractSocket::TcpSocket) socketTypeStr = QStringLiteral("TcpSocket"); diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 3dff11ec32..72f85c831f 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Intel Corporation. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtNetwork module of the Qt Toolkit. @@ -195,6 +196,64 @@ static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, const qt } } +static void convertToLevelAndOption(QNativeSocketEngine::SocketOption opt, + QAbstractSocket::NetworkLayerProtocol socketProtocol, int &level, int &n) +{ + n = 0; + level = SOL_SOCKET; // default + + switch (opt) { + case QNativeSocketEngine::NonBlockingSocketOption: // WSAIoctl + case QNativeSocketEngine::TypeOfServiceOption: // not supported + Q_UNREACHABLE(); + + case QNativeSocketEngine::ReceiveBufferSocketOption: + n = SO_RCVBUF; + break; + case QNativeSocketEngine::SendBufferSocketOption: + n = SO_SNDBUF; + break; + case QNativeSocketEngine::BroadcastSocketOption: + n = SO_BROADCAST; + break; + case QNativeSocketEngine::AddressReusable: + n = SO_REUSEADDR; + break; + case QNativeSocketEngine::BindExclusively: + n = SO_EXCLUSIVEADDRUSE; + break; + case QNativeSocketEngine::ReceiveOutOfBandData: + n = SO_OOBINLINE; + break; + case QNativeSocketEngine::LowDelayOption: + level = IPPROTO_TCP; + n = TCP_NODELAY; + break; + case QNativeSocketEngine::KeepAliveOption: + n = SO_KEEPALIVE; + break; + case QNativeSocketEngine::MulticastTtlOption: + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { + level = IPPROTO_IPV6; + n = IPV6_MULTICAST_HOPS; + } else + { + level = IPPROTO_IP; + n = IP_MULTICAST_TTL; + } + break; + case QNativeSocketEngine::MulticastLoopbackOption: + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { + level = IPPROTO_IPV6; + n = IPV6_MULTICAST_LOOP; + } else + { + level = IPPROTO_IP; + n = IP_MULTICAST_LOOP; + } + break; + } +} /*! \internal @@ -209,7 +268,7 @@ void QNativeSocketEnginePrivate::setPortAndAddress(sockaddr_in * sockAddrIPv4, q || socketProtocol == QAbstractSocket::AnyIPProtocol) { memset(sockAddrIPv6, 0, sizeof(qt_sockaddr_in6)); sockAddrIPv6->sin6_family = AF_INET6; - sockAddrIPv6->sin6_scope_id = address.scopeId().toInt(); + sockAddrIPv6->sin6_scope_id = address.scopeId().toUInt(); WSAHtons(socketDescriptor, port, &(sockAddrIPv6->sin6_port)); Q_IPV6ADDR tmp = address.toIPv6Address(); memcpy(&(sockAddrIPv6->sin6_addr.qt_s6_addr), &tmp, sizeof(tmp)); @@ -404,19 +463,8 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co if (!q->isValid()) return -1; - int n = -1; - int level = SOL_SOCKET; // default - + // handle non-getsockopt switch (opt) { - case QNativeSocketEngine::ReceiveBufferSocketOption: - n = SO_RCVBUF; - break; - case QNativeSocketEngine::SendBufferSocketOption: - n = SO_SNDBUF; - break; - case QNativeSocketEngine::BroadcastSocketOption: - n = SO_BROADCAST; - break; case QNativeSocketEngine::NonBlockingSocketOption: { unsigned long buf = 0; if (WSAIoctl(socketDescriptor, FIONBIO, 0,0, &buf, sizeof(buf), 0,0,0) == 0) @@ -425,53 +473,21 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co return -1; break; } - case QNativeSocketEngine::AddressReusable: - n = SO_REUSEADDR; - break; - case QNativeSocketEngine::BindExclusively: - n = SO_EXCLUSIVEADDRUSE; - break; - case QNativeSocketEngine::ReceiveOutOfBandData: - n = SO_OOBINLINE; - break; - case QNativeSocketEngine::LowDelayOption: - level = IPPROTO_TCP; - n = TCP_NODELAY; - break; - case QNativeSocketEngine::KeepAliveOption: - n = SO_KEEPALIVE; - break; - case QNativeSocketEngine::MulticastTtlOption: - - if (socketProtocol == QAbstractSocket::IPv6Protocol) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_HOPS; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_TTL; - } - break; - case QNativeSocketEngine::MulticastLoopbackOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_LOOP; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_LOOP; - } - break; case QNativeSocketEngine::TypeOfServiceOption: return -1; + + default: break; } #if Q_BYTE_ORDER != Q_LITTLE_ENDIAN #error code assumes windows is little endian #endif + int n, level; int v = 0; //note: windows doesn't write to all bytes if the option type is smaller than int QT_SOCKOPTLEN_T len = sizeof(v); + + convertToLevelAndOption(opt, socketProtocol, level, n); if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) == 0) return v; WS_ERROR_DEBUG(WSAGetLastError()); @@ -488,21 +504,12 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt if (!q->isValid()) return false; - int n = 0; - int level = SOL_SOCKET; // default - + // handle non-setsockopt options switch (opt) { - case QNativeSocketEngine::ReceiveBufferSocketOption: - n = SO_RCVBUF; - break; case QNativeSocketEngine::SendBufferSocketOption: // see QTBUG-30478 SO_SNDBUF should not be used on Vista or later if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA) return false; - n = SO_SNDBUF; - break; - case QNativeSocketEngine::BroadcastSocketOption: - n = SO_BROADCAST; break; case QNativeSocketEngine::NonBlockingSocketOption: { @@ -516,47 +523,15 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt return true; break; } - case QNativeSocketEngine::AddressReusable: - n = SO_REUSEADDR; - break; - case QNativeSocketEngine::BindExclusively: - n = SO_EXCLUSIVEADDRUSE; - break; - case QNativeSocketEngine::ReceiveOutOfBandData: - n = SO_OOBINLINE; - break; - case QNativeSocketEngine::LowDelayOption: - level = IPPROTO_TCP; - n = TCP_NODELAY; - break; - case QNativeSocketEngine::KeepAliveOption: - n = SO_KEEPALIVE; - break; - case QNativeSocketEngine::MulticastTtlOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_HOPS; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_TTL; - } - break; - case QNativeSocketEngine::MulticastLoopbackOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_LOOP; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_LOOP; - } - break; case QNativeSocketEngine::TypeOfServiceOption: return false; + + default: break; } + int n, level; + convertToLevelAndOption(opt, socketProtocol, level, n); if (::setsockopt(socketDescriptor, level, n, (char*)&v, sizeof(v)) != 0) { WS_ERROR_DEBUG(WSAGetLastError()); return false; @@ -658,7 +633,7 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin setPortAndAddress(&sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize); - if (socketProtocol == QAbstractSocket::IPv6Protocol && address.toIPv4Address()) { + if ((socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) && address.toIPv4Address()) { //IPV6_V6ONLY option must be cleared to connect to a V4 mapped address if (QSysInfo::windowsVersion() >= QSysInfo::WV_6_0) { DWORD ipv6only = 0; @@ -1035,7 +1010,7 @@ bool QNativeSocketEnginePrivate::nativeLeaveMulticastGroup(const QHostAddress &g QNetworkInterface QNativeSocketEnginePrivate::nativeMulticastInterface() const { - if (socketProtocol == QAbstractSocket::IPv6Protocol) { + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { uint v; QT_SOCKOPTLEN_T sizeofv = sizeof(v); if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *) &v, &sizeofv) == -1) @@ -1069,7 +1044,7 @@ QNetworkInterface QNativeSocketEnginePrivate::nativeMulticastInterface() const bool QNativeSocketEnginePrivate::nativeSetMulticastInterface(const QNetworkInterface &iface) { - if (socketProtocol == QAbstractSocket::IPv6Protocol) { + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { uint v = iface.isValid() ? iface.index() : 0; return (::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *) &v, sizeof(v)) != -1); } diff --git a/src/network/ssl/qsslcertificate_openssl.cpp b/src/network/ssl/qsslcertificate_openssl.cpp index 0ef845bf55..ad88ea5d56 100644 --- a/src/network/ssl/qsslcertificate_openssl.cpp +++ b/src/network/ssl/qsslcertificate_openssl.cpp @@ -691,7 +691,7 @@ QList<QSslCertificate> QSslCertificatePrivate::certificatesFromDer(const QByteAr } else { break; } - size -= ((char *)data - der.data()); + size -= ((const char *)data - der.data()); } return certificates; diff --git a/src/network/ssl/qsslkey_openssl.cpp b/src/network/ssl/qsslkey_openssl.cpp index 8741ab524f..33cb81ce71 100644 --- a/src/network/ssl/qsslkey_openssl.cpp +++ b/src/network/ssl/qsslkey_openssl.cpp @@ -139,7 +139,7 @@ void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhra if (!bio) return; - void *phrase = (void *)passPhrase.constData(); + void *phrase = const_cast<char *>(passPhrase.constData()); if (algorithm == QSsl::Rsa) { RSA *result = (type == QSsl::PublicKey) @@ -201,7 +201,7 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const bio, rsa, // ### the cipher should be selectable in the API: passPhrase.isEmpty() ? (const EVP_CIPHER *)0 : q_EVP_des_ede3_cbc(), - (uchar *)passPhrase.data(), passPhrase.size(), 0, 0)) { + const_cast<uchar *>((const uchar *)passPhrase.data()), passPhrase.size(), 0, 0)) { fail = true; } } @@ -214,7 +214,7 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const bio, dsa, // ### the cipher should be selectable in the API: passPhrase.isEmpty() ? (const EVP_CIPHER *)0 : q_EVP_des_ede3_cbc(), - (uchar *)passPhrase.data(), passPhrase.size(), 0, 0)) { + const_cast<uchar *>((const uchar *)passPhrase.data()), passPhrase.size(), 0, 0)) { fail = true; } } @@ -228,7 +228,7 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const bio, ec, // ### the cipher should be selectable in the API: passPhrase.isEmpty() ? (const EVP_CIPHER *)0 : q_EVP_des_ede3_cbc(), - (uchar *)passPhrase.data(), passPhrase.size(), 0, 0)) { + const_cast<uchar *>((const uchar *)passPhrase.data()), passPhrase.size(), 0, 0)) { fail = true; } } diff --git a/src/network/ssl/qsslkey_p.h b/src/network/ssl/qsslkey_p.h index acd16044e8..be981bb484 100644 --- a/src/network/ssl/qsslkey_p.h +++ b/src/network/ssl/qsslkey_p.h @@ -61,9 +61,10 @@ class QSslKeyPrivate { public: inline QSslKeyPrivate() - : opaque(0) + : algorithm(QSsl::Opaque) + , opaque(0) { - clear(); + clear(false); } inline ~QSslKeyPrivate() diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index 3326362d66..e833bb70c5 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -942,6 +942,15 @@ bool QSslSocketBackendPrivate::setSessionProtocol() return err == noErr; } +bool QSslSocketBackendPrivate::canIgnoreTrustVerificationFailure() const +{ + const QSslSocket::PeerVerifyMode verifyMode = configuration.peerVerifyMode; + return mode == QSslSocket::SslServerMode + && (verifyMode == QSslSocket::QueryPeer + || verifyMode == QSslSocket::AutoVerifyPeer + || verifyMode == QSslSocket::VerifyNone); +} + bool QSslSocketBackendPrivate::verifySessionProtocol() const { bool protocolOk = false; @@ -962,10 +971,7 @@ bool QSslSocketBackendPrivate::verifyPeerTrust() Q_Q(QSslSocket); const QSslSocket::PeerVerifyMode verifyMode = configuration.peerVerifyMode; - const bool canIgnoreVerify = mode == QSslSocket::SslServerMode - && (verifyMode == QSslSocket::QueryPeer - || verifyMode == QSslSocket::AutoVerifyPeer - || verifyMode == QSslSocket::VerifyNone); + const bool canIgnoreVerify = canIgnoreTrustVerificationFailure(); Q_ASSERT_X(context, Q_FUNC_INFO, "invalid SSL context (null)"); Q_ASSERT(plainSocket); @@ -1164,6 +1170,13 @@ bool QSslSocketBackendPrivate::startHandshake() return startHandshake(); } } else if (err != errSecSuccess) { + if (err == errSSLBadCert && canIgnoreTrustVerificationFailure()) { + // We're on the server side and client did not provide any + // certificate. This is the new 'nice' error returned by + // Security Framework after it was recently updated. + return startHandshake(); + } + setError(QStringLiteral("Error during SSL handshake: %1").arg(err), QAbstractSocket::SslHandshakeFailedError); plainSocket->disconnectFromHost(); diff --git a/src/network/ssl/qsslsocket_mac_p.h b/src/network/ssl/qsslsocket_mac_p.h index 4901a8576f..868b816957 100644 --- a/src/network/ssl/qsslsocket_mac_p.h +++ b/src/network/ssl/qsslsocket_mac_p.h @@ -94,6 +94,7 @@ private: QAbstractSocket::SocketError &errorCode); bool setSessionProtocol(); // Aux. functions to do a verification during handshake phase: + bool canIgnoreTrustVerificationFailure() const; bool verifySessionProtocol() const; bool verifyPeerTrust(); diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 4c1fc0f768..4d092a8109 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -687,7 +687,7 @@ void QSslSocketPrivate::resetDefaultEllipticCurves() if (q_EC_get_builtin_curves(builtinCurves.data(), curveCount) == curveCount) { for (size_t i = 0; i < curveCount; ++i) { QSslEllipticCurve curve; - curve.id = builtinCurves[i].nid; + curve.id = builtinCurves[int(i)].nid; curves.append(curve); } } diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_p.h b/src/platformsupport/devicediscovery/qdevicediscovery_p.h index 88b75ee439..637a74cb1f 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_p.h +++ b/src/platformsupport/devicediscovery/qdevicediscovery_p.h @@ -74,7 +74,8 @@ public: Device_DRM = 0x10, Device_DRM_PrimaryGPU = 0x20, Device_Tablet = 0x40, - Device_InputMask = Device_Mouse | Device_Touchpad | Device_Touchscreen | Device_Keyboard | Device_Tablet, + Device_Joystick = 0x80, + Device_InputMask = Device_Mouse | Device_Touchpad | Device_Touchscreen | Device_Keyboard | Device_Tablet | Device_Joystick, Device_VideoMask = Device_DRM }; Q_DECLARE_FLAGS(QDeviceTypes, QDeviceType) diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp index 160fb7f5c0..1bc834b5ef 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp +++ b/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp @@ -38,6 +38,7 @@ #include <QObject> #include <QHash> #include <QDir> +#include <QLoggingCategory> #include <QtCore/private/qcore_unix_p.h> #include <linux/input.h> @@ -56,13 +57,6 @@ #define ABS_CNT (ABS_MAX+1) #endif - -//#define QT_QPA_DEVICE_DISCOVERY_DEBUG - -#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG -#include <QtDebug> -#endif - #define LONG_BITS (sizeof(long) * 8 ) #define LONG_FIELD_SIZE(bits) ((bits / LONG_BITS) + 1) @@ -73,6 +67,8 @@ static bool testBit(long bit, const long *field) QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcDD, "qt.qpa.input") + QDeviceDiscovery *QDeviceDiscovery::create(QDeviceTypes types, QObject *parent) { return new QDeviceDiscoveryStatic(types, parent); @@ -81,9 +77,7 @@ QDeviceDiscovery *QDeviceDiscovery::create(QDeviceTypes types, QObject *parent) QDeviceDiscoveryStatic::QDeviceDiscoveryStatic(QDeviceTypes types, QObject *parent) : QDeviceDiscovery(types, parent) { -#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG - qWarning() << "New DeviceDiscovery created for type" << types; -#endif + qCDebug(lcDD) << "static device discovery for type" << types; } QStringList QDeviceDiscoveryStatic::scanConnectedDevices() @@ -112,9 +106,7 @@ QStringList QDeviceDiscoveryStatic::scanConnectedDevices() } } -#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG - qWarning() << "DeviceDiscovery found matching devices" << devices; -#endif + qCDebug(lcDD) << "Found matching devices" << devices; return devices; } @@ -124,9 +116,7 @@ bool QDeviceDiscoveryStatic::checkDeviceType(const QString &device) bool ret = false; int fd = QT_OPEN(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); if (!fd) { -#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG - qWarning() << "DeviceDiscovery cannot open device" << device; -#endif + qWarning() << "Device discovery cannot open device" << device; return false; } @@ -134,9 +124,7 @@ bool QDeviceDiscoveryStatic::checkDeviceType(const QString &device) if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(bitsKey)), bitsKey) >= 0 ) { if (!ret && (m_types & Device_Keyboard)) { if (testBit(KEY_Q, bitsKey)) { -#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG - qWarning() << "DeviceDiscovery found keyboard at" << device; -#endif + qCDebug(lcDD) << "Found keyboard at" << device; ret = true; } } @@ -145,9 +133,7 @@ bool QDeviceDiscoveryStatic::checkDeviceType(const QString &device) long bitsRel[LONG_FIELD_SIZE(REL_CNT)]; if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(bitsRel)), bitsRel) >= 0 ) { if (testBit(REL_X, bitsRel) && testBit(REL_Y, bitsRel) && testBit(BTN_MOUSE, bitsKey)) { -#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG - qWarning() << "DeviceDiscovery found mouse at" << device; -#endif + qCDebug(lcDD) << "Found mouse at" << device; ret = true; } } @@ -158,24 +144,29 @@ bool QDeviceDiscoveryStatic::checkDeviceType(const QString &device) if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(bitsAbs)), bitsAbs) >= 0 ) { if (testBit(ABS_X, bitsAbs) && testBit(ABS_Y, bitsAbs)) { if ((m_types & Device_Touchpad) && testBit(BTN_TOOL_FINGER, bitsKey)) { -#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG - qWarning() << "DeviceDiscovery found touchpad at" << device; -#endif + qCDebug(lcDD) << "Found touchpad at" << device; ret = true; } else if ((m_types & Device_Touchscreen) && testBit(BTN_TOUCH, bitsKey)) { -#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG - qWarning() << "DeviceDiscovery found touchscreen at" << device; -#endif + qCDebug(lcDD) << "Found touchscreen at" << device; ret = true; } else if ((m_types & Device_Tablet) && (testBit(BTN_STYLUS, bitsKey) || testBit(BTN_TOOL_PEN, bitsKey))) { -#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG - qWarning() << "DeviceDiscovery found tablet at" << device; -#endif + qCDebug(lcDD) << "Found tablet at" << device; ret = true; } } } } + + if (!ret && (m_types & Device_Joystick)) { + long bitsAbs[LONG_FIELD_SIZE(ABS_CNT)]; + if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(bitsAbs)), bitsAbs) >= 0 ) { + if ((m_types & Device_Joystick) + && (testBit(BTN_A, bitsKey) || testBit(BTN_TRIGGER, bitsKey) || testBit(ABS_RX, bitsAbs))) { + qCDebug(lcDD) << "Found joystick/gamepad at" << device; + ret = true; + } + } + } } if (!ret && (m_types & Device_DRM) && device.contains(QString::fromLatin1(QT_DRM_DEVICE_PREFIX))) diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp index 358be828fa..8fa82e2ad7 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp +++ b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp @@ -38,22 +38,17 @@ #include <QObject> #include <QHash> #include <QSocketNotifier> +#include <QLoggingCategory> #include <linux/input.h> -//#define QT_QPA_DEVICE_DISCOVERY_DEBUG - -#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG -#include <QtDebug> -#endif - QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcDD, "qt.qpa.input") + QDeviceDiscovery *QDeviceDiscovery::create(QDeviceTypes types, QObject *parent) { -#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG - qWarning() << "Try to create new UDeviceHelper"; -#endif + qCDebug(lcDD) << "udev device discovery for type" << types; QDeviceDiscovery *helper = 0; struct udev *udev; @@ -62,7 +57,7 @@ QDeviceDiscovery *QDeviceDiscovery::create(QDeviceTypes types, QObject *parent) if (udev) { helper = new QDeviceDiscoveryUDev(types, udev, parent); } else { - qWarning("Failed to get udev library context."); + qWarning("Failed to get udev library context"); } return helper; @@ -72,18 +67,12 @@ QDeviceDiscoveryUDev::QDeviceDiscoveryUDev(QDeviceTypes types, struct udev *udev QDeviceDiscovery(types, parent), m_udev(udev), m_udevMonitor(0), m_udevMonitorFileDescriptor(-1), m_udevSocketNotifier(0) { -#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG - qWarning() << "New UDeviceHelper created for type" << types; -#endif - if (!m_udev) return; m_udevMonitor = udev_monitor_new_from_netlink(m_udev, "udev"); if (!m_udevMonitor) { -#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG - qWarning("Unable to create an Udev monitor. No devices can be detected."); -#endif + qWarning("Unable to create an udev monitor. No devices can be detected."); return; } @@ -128,11 +117,11 @@ QStringList QDeviceDiscoveryUDev::scanConnectedDevices() } if (m_types & Device_Tablet) udev_enumerate_add_match_property(ue, "ID_INPUT_TABLET", "1"); + if (m_types & Device_Joystick) + udev_enumerate_add_match_property(ue, "ID_INPUT_JOYSTICK", "1"); if (udev_enumerate_scan_devices(ue) != 0) { -#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG - qWarning() << "UDeviceHelper scan connected devices for enumeration failed"; -#endif + qWarning("Failed to scan devices"); return devices; } @@ -158,9 +147,7 @@ QStringList QDeviceDiscoveryUDev::scanConnectedDevices() } udev_enumerate_unref(ue); -#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG - qWarning() << "UDeviceHelper found matching devices" << devices; -#endif + qCDebug(lcDD) << "Found matching devices" << devices; return devices; } @@ -251,6 +238,9 @@ bool QDeviceDiscoveryUDev::checkDeviceType(udev_device *dev) if ((m_types & Device_Tablet) && (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TABLET"), "1") == 0)) return true; + if ((m_types & Device_Joystick) && (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK"), "1") == 0)) + return true; + if ((m_types & Device_DRM) && (qstrcmp(udev_device_get_subsystem(dev), "drm") == 0)) return true; diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp index 011e2c2961..922455c96f 100644 --- a/src/platformsupport/eglconvenience/qeglconvenience.cpp +++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp @@ -576,6 +576,33 @@ int q_screenDepthFromFb(int framebufferDevice) return depth; } +qreal q_refreshRateFromFb(int framebufferDevice) +{ + static qreal rate = 0; + +#ifdef Q_OS_LINUX + if (rate == 0) { + if (framebufferDevice != -1) { + struct fb_var_screeninfo vinfo; + if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) != -1) { + const quint64 quot = quint64(vinfo.left_margin + vinfo.right_margin + vinfo.xres + vinfo.hsync_len) + * quint64(vinfo.upper_margin + vinfo.lower_margin + vinfo.yres + vinfo.vsync_len) + * vinfo.pixclock; + if (quot) + rate = 1000000000000LLU / quot; + } else { + qWarning("eglconvenience: Could not query screen info"); + } + } + } +#endif + + if (rate == 0) + rate = 60; + + return rate; +} + #endif // Q_OS_UNIX QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglconvenience_p.h b/src/platformsupport/eglconvenience/qeglconvenience_p.h index 1d35545430..59441d8c9a 100644 --- a/src/platformsupport/eglconvenience/qeglconvenience_p.h +++ b/src/platformsupport/eglconvenience/qeglconvenience_p.h @@ -63,6 +63,7 @@ void q_printEglConfig(EGLDisplay display, EGLConfig config); QSizeF q_physicalScreenSizeFromFb(int framebufferDevice, const QSize &screenSize = QSize()); QSize q_screenSizeFromFb(int framebufferDevice); int q_screenDepthFromFb(int framebufferDevice); +qreal q_refreshRateFromFb(int framebufferDevice); #endif class QEglConfigChooser diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp index bf23d52465..09243487c7 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp @@ -43,6 +43,7 @@ #include "qeglplatformcursor_p.h" #include "qeglplatformintegration_p.h" +#include "qeglplatformscreen_p.h" QT_BEGIN_NAMESPACE @@ -56,7 +57,7 @@ QT_BEGIN_NAMESPACE QEGLPlatformCursor::QEGLPlatformCursor(QPlatformScreen *screen) : m_visible(true), - m_screen(screen), + m_screen(static_cast<QEGLPlatformScreen *>(screen)), m_program(0), m_vertexCoordEntry(0), m_textureCoordEntry(0), @@ -297,9 +298,11 @@ QPoint QEGLPlatformCursor::pos() const void QEGLPlatformCursor::setPos(const QPoint &pos) { + QGuiApplicationPrivate::inputDeviceManager()->setCursorPos(pos); const QRect oldCursorRect = cursorRect(); m_cursor.pos = pos; update(oldCursorRect | cursorRect()); + m_screen->handleCursorMove(m_cursor.pos); } void QEGLPlatformCursor::pointerEvent(const QMouseEvent &event) @@ -309,6 +312,7 @@ void QEGLPlatformCursor::pointerEvent(const QMouseEvent &event) const QRect oldCursorRect = cursorRect(); m_cursor.pos = event.screenPos().toPoint(); update(oldCursorRect | cursorRect()); + m_screen->handleCursorMove(m_cursor.pos); } void QEGLPlatformCursor::paintOnScreen() diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h index 481bb3c74c..b89dd1ca43 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h @@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE class QOpenGLShaderProgram; class QEGLPlatformCursor; +class QEGLPlatformScreen; class QEGLPlatformCursorDeviceListener : public QObject { @@ -127,7 +128,7 @@ private: } m_cursorAtlas; bool m_visible; - QPlatformScreen *m_screen; + QEGLPlatformScreen *m_screen; QOpenGLShaderProgram *m_program; int m_vertexCoordEntry; int m_textureCoordEntry; diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp index dd4a97cdf5..6e2fc81c42 100644 --- a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp @@ -32,6 +32,8 @@ ****************************************************************************/ #include "qeglplatformscreen_p.h" +#include <QtGui/qwindow.h> +#include <qpa/qwindowsysteminterface.h> #include <QtPlatformSupport/private/qopenglcompositor_p.h> QT_BEGIN_NAMESPACE @@ -45,7 +47,8 @@ QT_BEGIN_NAMESPACE */ QEGLPlatformScreen::QEGLPlatformScreen(EGLDisplay dpy) - : m_dpy(dpy) + : m_dpy(dpy), + m_pointerWindow(0) { } @@ -54,4 +57,41 @@ QEGLPlatformScreen::~QEGLPlatformScreen() QOpenGLCompositor::destroy(); } +void QEGLPlatformScreen::handleCursorMove(const QPoint &pos) +{ + const QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); + const QList<QOpenGLCompositorWindow *> windows = compositor->windows(); + + // Generate enter and leave events like a real windowing system would do. + if (windows.isEmpty()) + return; + + // First window is always fullscreen. + if (windows.count() == 1) { + QWindow *window = windows[0]->sourceWindow(); + if (m_pointerWindow != window) { + m_pointerWindow = window; + QWindowSystemInterface::handleEnterEvent(window, window->mapFromGlobal(pos), pos); + } + return; + } + + QWindow *enter = 0, *leave = 0; + for (int i = windows.count() - 1; i >= 0; --i) { + QWindow *window = windows[i]->sourceWindow(); + const QRect geom = window->geometry(); + if (geom.contains(pos)) { + if (m_pointerWindow != window) { + leave = m_pointerWindow; + m_pointerWindow = window; + enter = window; + } + break; + } + } + + if (enter && leave) + QWindowSystemInterface::handleEnterLeaveEvent(enter, leave, enter->mapFromGlobal(pos), pos); +} + QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h b/src/platformsupport/eglconvenience/qeglplatformscreen_p.h index 33528e61a7..98a108c4b7 100644 --- a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformscreen_p.h @@ -46,6 +46,7 @@ // #include <QtCore/QList> +#include <QtCore/QPoint> #include <QtCore/qtextstream.h> #include <qpa/qplatformscreen.h> #include <EGL/egl.h> @@ -53,6 +54,7 @@ QT_BEGIN_NAMESPACE class QOpenGLContext; +class QWindow; class QEGLPlatformWindow; class QEGLPlatformScreen : public QPlatformScreen @@ -63,8 +65,11 @@ public: EGLDisplay display() const { return m_dpy; } + void handleCursorMove(const QPoint &pos); + private: EGLDisplay m_dpy; + QWindow *m_pointerWindow; }; QT_END_NAMESPACE diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm b/src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm index bd0f89ba2f..13b7dc4358 100644 --- a/src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm +++ b/src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm @@ -268,6 +268,10 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag qUnIndent(); qEventDispatcherDebug() << "result = " << qPrintableResult(result); + eventsProcessed |= (result == kCFRunLoopRunHandledSource + || m_processEvents.processedPostedEvents + || m_processEvents.processedTimers); + if (result == kCFRunLoopRunFinished) { // This should only happen at application shutdown, as the main runloop // will presumably always have sources registered. @@ -302,10 +306,6 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag } } - eventsProcessed |= (result == kCFRunLoopRunHandledSource - || m_processEvents.processedPostedEvents - || m_processEvents.processedTimers); - if (m_processEvents.flags & QEventLoop::EventLoopExec) { // We were called from QEventLoop's exec(), which blocks until the event // loop is asked to exit by calling processEvents repeatedly. Instead of diff --git a/src/platformsupport/fbconvenience/qfbcursor.cpp b/src/platformsupport/fbconvenience/qfbcursor.cpp index 963d315998..c727d67e72 100644 --- a/src/platformsupport/fbconvenience/qfbcursor.cpp +++ b/src/platformsupport/fbconvenience/qfbcursor.cpp @@ -81,22 +81,34 @@ QRect QFbCursor::getCurrentRect() { QRect rect = mGraphic->image()->rect().translated(-mGraphic->hotspot().x(), -mGraphic->hotspot().y()); - rect.translate(QCursor::pos()); + rect.translate(m_pos); QPoint mScreenOffset = mScreen->geometry().topLeft(); rect.translate(-mScreenOffset); // global to local translation return rect; } +QPoint QFbCursor::pos() const +{ + return m_pos; +} -void QFbCursor::pointerEvent(const QMouseEvent & e) +void QFbCursor::setPos(const QPoint &pos) { - Q_UNUSED(e); - QPoint mScreenOffset = mScreen->geometry().topLeft(); + QGuiApplicationPrivate::inputDeviceManager()->setCursorPos(pos); + m_pos = pos; mCurrentRect = getCurrentRect(); - // global to local translation - if (mOnScreen || mScreen->geometry().intersects(mCurrentRect.translated(mScreenOffset))) { + if (mOnScreen || mScreen->geometry().intersects(mCurrentRect.translated(mScreen->geometry().topLeft()))) + setDirty(); +} + +void QFbCursor::pointerEvent(const QMouseEvent &e) +{ + if (e.type() != QEvent::MouseMove) + return; + m_pos = e.screenPos().toPoint(); + mCurrentRect = getCurrentRect(); + if (mOnScreen || mScreen->geometry().intersects(mCurrentRect.translated(mScreen->geometry().topLeft()))) setDirty(); - } } QRect QFbCursor::drawCursor(QPainter & painter) diff --git a/src/platformsupport/fbconvenience/qfbcursor_p.h b/src/platformsupport/fbconvenience/qfbcursor_p.h index fe3aeada4c..9c5506b455 100644 --- a/src/platformsupport/fbconvenience/qfbcursor_p.h +++ b/src/platformsupport/fbconvenience/qfbcursor_p.h @@ -81,9 +81,11 @@ public: virtual QRect drawCursor(QPainter &painter); // input methods - virtual void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE; + void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE; + QPoint pos() const Q_DECL_OVERRIDE; + void setPos(const QPoint &pos) Q_DECL_OVERRIDE; #ifndef QT_NO_CURSOR - virtual void changeCursor(QCursor *widgetCursor, QWindow *window) Q_DECL_OVERRIDE; + void changeCursor(QCursor *widgetCursor, QWindow *window) Q_DECL_OVERRIDE; #endif virtual void setDirty(); @@ -107,6 +109,7 @@ private: bool mOnScreen; QPlatformCursorImage *mGraphic; QFbCursorDeviceListener *mDeviceListener; + QPoint m_pos; }; QT_END_NAMESPACE diff --git a/src/platformsupport/fontdatabases/basic/basic.pri b/src/platformsupport/fontdatabases/basic/basic.pri index 568cdf8ee7..c09ea4eed5 100644 --- a/src/platformsupport/fontdatabases/basic/basic.pri +++ b/src/platformsupport/fontdatabases/basic/basic.pri @@ -11,78 +11,7 @@ SOURCES += \ CONFIG += opentype contains(QT_CONFIG, freetype) { - QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype - SOURCES += \ - $$QT_FREETYPE_DIR/src/base/ftbase.c \ - $$QT_FREETYPE_DIR/src/base/ftbbox.c \ - $$QT_FREETYPE_DIR/src/base/ftdebug.c \ - $$QT_FREETYPE_DIR/src/base/ftglyph.c \ - $$QT_FREETYPE_DIR/src/base/ftlcdfil.c \ - $$QT_FREETYPE_DIR/src/base/ftinit.c \ - $$QT_FREETYPE_DIR/src/base/ftmm.c \ - $$QT_FREETYPE_DIR/src/base/fttype1.c \ - $$QT_FREETYPE_DIR/src/base/ftsynth.c \ - $$QT_FREETYPE_DIR/src/base/ftbitmap.c \ - $$QT_FREETYPE_DIR/src/bdf/bdf.c \ - $$QT_FREETYPE_DIR/src/cache/ftcache.c \ - $$QT_FREETYPE_DIR/src/cff/cff.c \ - $$QT_FREETYPE_DIR/src/cid/type1cid.c \ - $$QT_FREETYPE_DIR/src/gzip/ftgzip.c \ - $$QT_FREETYPE_DIR/src/pcf/pcf.c \ - $$QT_FREETYPE_DIR/src/pfr/pfr.c \ - $$QT_FREETYPE_DIR/src/psaux/psaux.c \ - $$QT_FREETYPE_DIR/src/pshinter/pshinter.c \ - $$QT_FREETYPE_DIR/src/psnames/psmodule.c \ - $$QT_FREETYPE_DIR/src/raster/raster.c \ - $$QT_FREETYPE_DIR/src/sfnt/sfnt.c \ - $$QT_FREETYPE_DIR/src/smooth/smooth.c \ - $$QT_FREETYPE_DIR/src/truetype/truetype.c \ - $$QT_FREETYPE_DIR/src/type1/type1.c \ - $$QT_FREETYPE_DIR/src/type42/type42.c \ - $$QT_FREETYPE_DIR/src/winfonts/winfnt.c \ - $$QT_FREETYPE_DIR/src/lzw/ftlzw.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvalid.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvbase.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvgdef.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvjstf.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvcommn.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvgpos.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvgsub.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvmod.c\ - $$QT_FREETYPE_DIR/src/autofit/afangles.c\ - $$QT_FREETYPE_DIR/src/autofit/afglobal.c\ - $$QT_FREETYPE_DIR/src/autofit/aflatin.c\ - $$QT_FREETYPE_DIR/src/autofit/afmodule.c\ - $$QT_FREETYPE_DIR/src/autofit/afdummy.c\ - $$QT_FREETYPE_DIR/src/autofit/afhints.c\ - $$QT_FREETYPE_DIR/src/autofit/afloader.c\ - $$QT_FREETYPE_DIR/src/autofit/autofit.c - - win32 { - SOURCES += \ - $$QT_FREETYPE_DIR/src/base/ftsystem.c - } else { - SOURCES += \ - $$QT_FREETYPE_DIR/builds/unix/ftsystem.c - INCLUDEPATH += \ - $$QT_FREETYPE_DIR/builds/unix - } - - # disable warnings about "unsafe" methods in C code - msvc:QMAKE_CFLAGS_WARN_ON += -wd"4996" - - INCLUDEPATH += \ - $$QT_FREETYPE_DIR/src \ - $$QT_FREETYPE_DIR/include - - TR_EXCLUDE += $$QT_FREETYPE_DIR/* - - DEFINES += FT2_BUILD_LIBRARY - contains(QT_CONFIG, system-zlib) { - DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB - include($$PWD/../../../3rdparty/zlib_dependency.pri) - } - + include($$QT_SOURCE_TREE/src/3rdparty/freetype.pri) } else:contains(QT_CONFIG, system-freetype) { # pull in the proper freetype2 include directory include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri) diff --git a/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp b/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp index 6eb1fccba0..805397f021 100644 --- a/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp +++ b/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp @@ -92,6 +92,9 @@ QEvdevMouseManager::QEvdevMouseManager(const QString &key, const QString &specif connect(m_deviceDiscovery, SIGNAL(deviceRemoved(QString)), this, SLOT(removeMouse(QString))); } } + + connect(QGuiApplicationPrivate::inputDeviceManager(), SIGNAL(cursorPositionChangeRequested(QPoint)), + this, SLOT(handleCursorPositionChange(QPoint))); } QEvdevMouseManager::~QEvdevMouseManager() @@ -100,17 +103,8 @@ QEvdevMouseManager::~QEvdevMouseManager() m_mice.clear(); } -void QEvdevMouseManager::handleMouseEvent(int x, int y, bool abs, Qt::MouseButtons buttons) +void QEvdevMouseManager::clampPosition() { - // update current absolute coordinates - if (!abs) { - m_x += x; - m_y += y; - } else { - m_x = x; - m_y = y; - } - // clamp to screen geometry QRect g = QGuiApplication::primaryScreen()->virtualGeometry(); if (m_x + m_xoffset < g.left()) @@ -122,6 +116,20 @@ void QEvdevMouseManager::handleMouseEvent(int x, int y, bool abs, Qt::MouseButto m_y = g.top() - m_yoffset; else if (m_y + m_yoffset > g.bottom()) m_y = g.bottom() - m_yoffset; +} + +void QEvdevMouseManager::handleMouseEvent(int x, int y, bool abs, Qt::MouseButtons buttons) +{ + // update current absolute coordinates + if (!abs) { + m_x += x; + m_y += y; + } else { + m_x = x; + m_y = y; + } + + clampPosition(); QPoint pos(m_x + m_xoffset, m_y + m_yoffset); // Cannot track the keyboard modifiers ourselves here. Instead, report the @@ -163,4 +171,11 @@ void QEvdevMouseManager::removeMouse(const QString &deviceNode) } } +void QEvdevMouseManager::handleCursorPositionChange(const QPoint &pos) +{ + m_x = pos.x(); + m_y = pos.y(); + clampPosition(); +} + QT_END_NAMESPACE diff --git a/src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h b/src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h index 944effd80b..e1b24b807d 100644 --- a/src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h +++ b/src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h @@ -69,8 +69,11 @@ public slots: private slots: void addMouse(const QString &deviceNode = QString()); void removeMouse(const QString &deviceNode); + void handleCursorPositionChange(const QPoint &pos); private: + void clampPosition(); + QString m_spec; QHash<QString,QEvdevMouseHandler*> m_mice; QDeviceDiscovery *m_deviceDiscovery; diff --git a/src/platformsupport/input/evdevtouch/qevdevtouch.cpp b/src/platformsupport/input/evdevtouch/qevdevtouch.cpp index 5215f7da0a..5c28dfb082 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouch.cpp +++ b/src/platformsupport/input/evdevtouch/qevdevtouch.cpp @@ -175,7 +175,7 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &specification, setObjectName(QLatin1String("Evdev Touch Handler")); if (qEnvironmentVariableIsSet("QT_QPA_EVDEV_DEBUG")) - ((QLoggingCategory &) qLcEvdevTouch()).setEnabled(QtDebugMsg, true); + const_cast<QLoggingCategory &>(qLcEvdevTouch()).setEnabled(QtDebugMsg, true); // only the first device argument is used for now QString spec = QString::fromLocal8Bit(qgetenv("QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS")); diff --git a/src/platformsupport/input/libinput/qlibinputhandler.cpp b/src/platformsupport/input/libinput/qlibinputhandler.cpp index 22b08960df..1a64ad5a30 100644 --- a/src/platformsupport/input/libinput/qlibinputhandler.cpp +++ b/src/platformsupport/input/libinput/qlibinputhandler.cpp @@ -107,6 +107,9 @@ QLibInputHandler::QLibInputHandler(const QString &key, const QString &spec) m_keyboard.reset(new QLibInputKeyboard); m_touch.reset(new QLibInputTouch); + connect(QGuiApplicationPrivate::inputDeviceManager(), SIGNAL(cursorPositionChangeRequested(QPoint)), + this, SLOT(onCursorPositionChangeRequested(QPoint))); + // Process the initial burst of DEVICE_ADDED events. onReadyRead(); } @@ -227,4 +230,9 @@ void QLibInputHandler::processEvent(libinput_event *ev) } } +void QLibInputHandler::onCursorPositionChangeRequested(const QPoint &pos) +{ + m_pointer->setPos(pos); +} + QT_END_NAMESPACE diff --git a/src/platformsupport/input/libinput/qlibinputhandler_p.h b/src/platformsupport/input/libinput/qlibinputhandler_p.h index 5d54f984de..de04d71f93 100644 --- a/src/platformsupport/input/libinput/qlibinputhandler_p.h +++ b/src/platformsupport/input/libinput/qlibinputhandler_p.h @@ -74,6 +74,7 @@ signals: private slots: void onReadyRead(); + void onCursorPositionChangeRequested(const QPoint &pos); private: void processEvent(libinput_event *ev); diff --git a/src/platformsupport/input/libinput/qlibinputpointer.cpp b/src/platformsupport/input/libinput/qlibinputpointer.cpp index 794ac54e8e..48e5a6cf1c 100644 --- a/src/platformsupport/input/libinput/qlibinputpointer.cpp +++ b/src/platformsupport/input/libinput/qlibinputpointer.cpp @@ -108,4 +108,11 @@ void QLibInputPointer::processAxis(libinput_event_pointer *e) #endif } +void QLibInputPointer::setPos(const QPoint &pos) +{ + const QRect g = QGuiApplication::primaryScreen()->virtualGeometry(); + m_pos.setX(qBound(g.left(), pos.x(), g.right())); + m_pos.setY(qBound(g.top(), pos.y(), g.bottom())); +} + QT_END_NAMESPACE diff --git a/src/platformsupport/input/libinput/qlibinputpointer_p.h b/src/platformsupport/input/libinput/qlibinputpointer_p.h index 3b0c5df1c6..a8ba19c7ec 100644 --- a/src/platformsupport/input/libinput/qlibinputpointer_p.h +++ b/src/platformsupport/input/libinput/qlibinputpointer_p.h @@ -60,6 +60,8 @@ public: void processMotion(libinput_event_pointer *e); void processAxis(libinput_event_pointer *e); + void setPos(const QPoint &pos); + private: QPoint m_pos; Qt::MouseButtons m_buttons; diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp index 6e5b81ed36..ab03bfeb04 100644 --- a/src/plugins/imageformats/ico/qicohandler.cpp +++ b/src/plugins/imageformats/ico/qicohandler.cpp @@ -524,7 +524,7 @@ QImage ICOReader::iconAt(int index) iod->seek(iconEntry.dwImageOffset); - const QByteArray pngMagic = QByteArray::fromRawData((char*)pngMagicData, sizeof(pngMagicData)); + const QByteArray pngMagic = QByteArray::fromRawData((const char*)pngMagicData, sizeof(pngMagicData)); const bool isPngImage = (iod->read(pngMagic.size()) == pngMagic); if (isPngImage) { diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp index ad226989a0..49fa32004e 100644 --- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp @@ -97,7 +97,7 @@ bool QComposeInputContext::filterEvent(const QEvent *event) if ((m_tableState & TableGenerator::NoErrors) != TableGenerator::NoErrors) return false; - QKeyEvent *keyEvent = (QKeyEvent *)event; + const QKeyEvent *keyEvent = (const QKeyEvent *)event; // should pass only the key presses if (keyEvent->type() != QEvent::KeyPress) { return false; diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h index d012ede5f9..3737584c4c 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.h +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h @@ -54,6 +54,7 @@ public: QImage toImage() const; void resize (const QSize &size, const QRegion &); bool scroll(const QRegion &area, int dx, int dy); + void beginPaint(const QRegion ®ion); qreal getBackingStoreDevicePixelRatio(); private: diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index cddb960197..6a4f7ed8ee 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -96,6 +96,18 @@ bool QCocoaBackingStore::scroll(const QRegion &area, int dx, int dy) return true; } +void QCocoaBackingStore::beginPaint(const QRegion ®ion) +{ + if (m_qImage.hasAlphaChannel()) { + QPainter p(&m_qImage); + p.setCompositionMode(QPainter::CompositionMode_Source); + const QVector<QRect> rects = region.rects(); + const QColor blank = Qt::transparent; + for (QVector<QRect>::const_iterator it = rects.begin(), end = rects.end(); it != end; ++it) + p.fillRect(*it, blank); + } +} + qreal QCocoaBackingStore::getBackingStoreDevicePixelRatio() { return m_qImage.devicePixelRatio(); diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm index 933034bb6f..d1802fe4f9 100644 --- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm @@ -84,20 +84,13 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont) QFont newFont; if (cocoaFont) { int pSize = qRound([cocoaFont pointSize]); - QString family(QCFString::toQString([cocoaFont familyName])); - QString typeface(QCFString::toQString([cocoaFont fontName])); - - int hyphenPos = typeface.indexOf(QLatin1Char('-')); - if (hyphenPos != -1) { - typeface.remove(0, hyphenPos + 1); - } else { - typeface = QLatin1String("Normal"); - } + QCFType<CTFontDescriptorRef> font(CTFontCopyFontDescriptor((CTFontRef)cocoaFont)); + QString family(QCFString((CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute))); + QString style(QCFString(((CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontStyleNameAttribute)))); - newFont = QFontDatabase().font(family, typeface, pSize); + newFont = QFontDatabase().font(family, style, pSize); newFont.setUnderline(resolveFont.underline()); newFont.setStrikeOut(resolveFont.strikeOut()); - } return newFont; } diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index 3b79717472..dc9140d990 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -133,6 +133,11 @@ public: void setToolbar(QWindow *window, NSToolbar *toolbar); NSToolbar *toolbar(QWindow *window) const; void clearToolbars(); + + void pushPopupWindow(QCocoaWindow *window); + QCocoaWindow *popPopupWindow(); + QCocoaWindow *activePopupWindow() const; + QList<QCocoaWindow *> *popupWindowStack(); private: static QCocoaIntegration *mInstance; @@ -151,6 +156,7 @@ private: QScopedPointer<QCocoaKeyMapper> mKeyboardMapper; QHash<QWindow *, NSToolbar *> mToolbars; + QList<QCocoaWindow *> m_popupWindowStack; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 881b23cd6f..aa33cfd8bc 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -545,4 +545,28 @@ void QCocoaIntegration::clearToolbars() mToolbars.clear(); } +void QCocoaIntegration::pushPopupWindow(QCocoaWindow *window) +{ + m_popupWindowStack.append(window); +} + +QCocoaWindow *QCocoaIntegration::popPopupWindow() +{ + if (m_popupWindowStack.isEmpty()) + return 0; + return m_popupWindowStack.takeLast(); +} + +QCocoaWindow *QCocoaIntegration::activePopupWindow() const +{ + if (m_popupWindowStack.isEmpty()) + return 0; + return m_popupWindowStack.front(); +} + +QList<QCocoaWindow *> *QCocoaIntegration::popupWindowStack() +{ + return &m_popupWindowStack; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index ad8821ca97..59807deb5a 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -58,6 +58,7 @@ public: void removeMenuItem(QPlatformMenuItem *menuItem); void syncMenuItem(QPlatformMenuItem *menuItem); void setEnabled(bool enabled); + bool isEnabled() const; void setVisible(bool visible); void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item); void dismiss(); diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index fb11efb689..4fadc2f60a 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -426,6 +426,11 @@ void QCocoaMenu::setEnabled(bool enabled) syncModalState(!m_enabled); } +bool QCocoaMenu::isEnabled() const +{ + return [m_nativeItem isEnabled]; +} + void QCocoaMenu::setVisible(bool visible) { [m_nativeItem setSubmenu:(visible ? m_nativeMenu : nil)]; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index e4794f8674..c87a871ad0 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -262,7 +262,6 @@ public: // for QNSView bool m_effectivelyMaximized; Qt::WindowState m_synchedWindowState; Qt::WindowModality m_windowModality; - QPointer<QWindow> m_activePopupWindow; QPointer<QWindow> m_enterLeaveTargetWindow; bool m_windowUnderMouse; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index b9a09d03b5..8aed9da9c5 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -455,6 +455,10 @@ QCocoaWindow::~QCocoaWindow() [m_qtView clearQWindowPointers]; } + // While it is unlikely that this window will be in the popup stack + // during deletetion we clear any pointers here to make sure. + QCocoaIntegration::instance()->popupWindowStack()->removeAll(this); + foreach (QCocoaWindow *child, m_childWindows) { [m_nsWindow removeChildWindow:child->m_nsWindow]; child->m_parentCocoaWindow = 0; @@ -647,17 +651,17 @@ void QCocoaWindow::setVisible(bool visible) // We need to recreate if the modality has changed as the style mask will need updating if (m_windowModality != window()->modality()) recreateWindow(parent()); + + // Register popup windows. The Cocoa platform plugin will forward mouse events + // to them and close them when needed. + if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip) + QCocoaIntegration::instance()->pushPopupWindow(this); + if (parentCocoaWindow) { // The parent window might have moved while this window was hidden, // update the window geometry if there is a parent. setGeometry(window()->geometry()); - // Register popup windows so that the parent window can close them when needed. - if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip) { - // qDebug() << "transientParent and popup" << window()->type() << Qt::Popup << (window()->type() & Qt::Popup); - parentCocoaWindow->m_activePopupWindow = window(); - } - if (window()->type() == Qt::Popup) { // QTBUG-30266: a window should not be resizable while a transient popup is open // Since this isn't a native popup, the window manager doesn't close the popup when you click outside @@ -759,8 +763,11 @@ void QCocoaWindow::setVisible(bool visible) [NSEvent removeMonitor:monitor]; monitor = nil; } + + if (window()->type() == Qt::Popup) + QCocoaIntegration::instance()->popupWindowStack()->removeAll(this); + if (parentCocoaWindow && window()->type() == Qt::Popup) { - parentCocoaWindow->m_activePopupWindow = 0; if (m_resizableTransientParent && !([parentCocoaWindow->m_nsWindow styleMask] & NSFullScreenWindowMask)) // QTBUG-30266: a window should not be resizable while a transient popup is open @@ -1177,10 +1184,9 @@ void QCocoaWindow::setEmbeddedInForeignView(bool embedded) void QCocoaWindow::windowWillMove() { // Close any open popups on window move - if (m_activePopupWindow) { - QWindowSystemInterface::handleCloseEvent(m_activePopupWindow); + while (QCocoaWindow *popup = QCocoaIntegration::instance()->popPopupWindow()) { + QWindowSystemInterface::handleCloseEvent(popup->window()); QWindowSystemInterface::flushWindowSystemEvents(); - m_activePopupWindow = 0; } } diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 39bd5d486c..1c87b90450 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -699,6 +699,10 @@ QT_WARNING_POP m_platformWindow->m_forwardWindow = 0; } + // Popups implicitly grap mouse events; forward to the active popup if there is one + if (QCocoaWindow *popup = QCocoaIntegration::instance()->activePopupWindow()) + targetView = popup->contentView(); + [targetView convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint]; ulong timestamp = [theEvent timestamp] * 1000; @@ -766,16 +770,39 @@ QT_WARNING_POP if (m_window->flags() & Qt::WindowTransparentForInput) return [super mouseDown:theEvent]; m_sendUpAsRightButton = false; - if (m_platformWindow->m_activePopupWindow) { - Qt::WindowType type = m_platformWindow->m_activePopupWindow->type(); - QWindowSystemInterface::handleCloseEvent(m_platformWindow->m_activePopupWindow); - QWindowSystemInterface::flushWindowSystemEvents(); - m_platformWindow->m_activePopupWindow = 0; - // Consume the mouse event when closing the popup, except for tool tips - // were it's expected that the event is processed normally. - if (type != Qt::ToolTip) - return; + + // Handle any active poup windows; clicking outisde them should close them + // all. Don't do anything or clicks inside one of the menus, let Cocoa + // handle that case. Note that in practice many windows of the Qt::Popup type + // will actually close themselves in this case using logic implemented in + // that particular poup type (for example context menus). However, Qt expects + // that plain popup QWindows will also be closed, so we implement the logic + // here as well. + QList<QCocoaWindow *> *popups = QCocoaIntegration::instance()->popupWindowStack(); + if (!popups->isEmpty()) { + // Check if the click is outside all popups. + bool inside = false; + QPointF qtScreenPoint = qt_mac_flipPoint([self screenMousePoint:theEvent]); + for (QList<QCocoaWindow *>::const_iterator it = popups->begin(); it != popups->end(); ++it) { + if ((*it)->geometry().contains(qtScreenPoint.toPoint())) { + inside = true; + break; + } + } + // Close the popups if the click was outside. + if (!inside) { + Qt::WindowType type = QCocoaIntegration::instance()->activePopupWindow()->window()->type(); + while (QCocoaWindow *popup = QCocoaIntegration::instance()->popPopupWindow()) { + QWindowSystemInterface::handleCloseEvent(popup->window()); + QWindowSystemInterface::flushWindowSystemEvents(); + } + // Consume the mouse event when closing the popup, except for tool tips + // were it's expected that the event is processed normally. + if (type != Qt::ToolTip) + return; + } } + if ([self hasMarkedText]) { NSInputManager* inputManager = [NSInputManager currentInputManager]; if ([inputManager wantsToHandleMouseEvents]) { diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp index 30fcf8143f..bafe1e3324 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp @@ -96,19 +96,19 @@ static const char * const connector_type_names[] = { "eDP", }; -static QString nameForConnector(const drmModeConnectorPtr connector) +static QByteArray nameForConnector(const drmModeConnectorPtr connector) { - QString connectorName = "UNKNOWN"; + QByteArray connectorName("UNKNOWN"); if (connector->connector_type < ARRAY_LENGTH(connector_type_names)) connectorName = connector_type_names[connector->connector_type]; - connectorName += QString::number(connector->connector_type_id); + connectorName += QByteArray::number(connector->connector_type_id); return connectorName; } -static bool parseModeline(const QString &s, drmModeModeInfoPtr mode) +static bool parseModeline(const QByteArray &text, drmModeModeInfoPtr mode) { char hsync[16]; char vsync[16]; @@ -120,7 +120,7 @@ static bool parseModeline(const QString &s, drmModeModeInfoPtr mode) mode->vrefresh = 0; mode->flags = 0; - if (sscanf(qPrintable(s), "%f %hd %hd %hd %hd %hd %hd %hd %hd %15s %15s", + if (sscanf(text.constData(), "%f %hd %hd %hd %hd %hd %hd %hd %hd %15s %15s", &fclock, &mode->hdisplay, &mode->hsync_start, @@ -153,7 +153,7 @@ static bool parseModeline(const QString &s, drmModeModeInfoPtr mode) QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, QPoint pos) { - const QString connectorName = nameForConnector(connector); + const QByteArray connectorName = nameForConnector(connector); const int crtc = crtcForConnector(resources, connector); if (crtc < 0) { @@ -165,19 +165,20 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr QSize configurationSize; drmModeModeInfo configurationModeline; - const QString mode = m_integration->outputSettings().value(connectorName).value("mode", "preferred").toString().toLower(); + const QByteArray mode = m_integration->outputSettings().value(QString::fromUtf8(connectorName)) + .value(QStringLiteral("mode"), QStringLiteral("preferred")).toByteArray().toLower(); if (mode == "off") { configuration = OutputConfigOff; } else if (mode == "preferred") { configuration = OutputConfigPreferred; } else if (mode == "current") { configuration = OutputConfigCurrent; - } else if (sscanf(qPrintable(mode), "%dx%d", &configurationSize.rwidth(), &configurationSize.rheight()) == 2) { + } else if (sscanf(mode.constData(), "%dx%d", &configurationSize.rwidth(), &configurationSize.rheight()) == 2) { configuration = OutputConfigMode; } else if (parseModeline(mode, &configurationModeline)) { configuration = OutputConfigModeline; } else { - qWarning("Invalid mode \"%s\" for output %s", qPrintable(mode), qPrintable(connectorName)); + qWarning("Invalid mode \"%s\" for output %s", mode.constData(), connectorName.constData()); configuration = OutputConfigPreferred; } @@ -273,7 +274,7 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr } QEglFSKmsOutput output = { - connectorName, + QString::fromUtf8(connectorName), connector->connector_id, crtc_id, QSizeF(connector->mmWidth, connector->mmHeight), diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp index 4598f21d92..7bb932cf00 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp @@ -223,25 +223,25 @@ void QEglFSKmsIntegration::loadConfig() return; } - QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); + const QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); if (!doc.isObject()) { qCDebug(qLcEglfsKmsDebug) << "Invalid config file" << json << "- no top-level JSON object"; return; } - QJsonObject object = doc.object(); + const QJsonObject object = doc.object(); - m_hwCursor = object.value("hwcursor").toBool(m_hwCursor); - m_pbuffers = object.value("pbuffers").toBool(m_pbuffers); - m_devicePath = object.value("device").toString(); + m_hwCursor = object.value(QStringLiteral("hwcursor")).toBool(m_hwCursor); + m_pbuffers = object.value(QStringLiteral("pbuffers")).toBool(m_pbuffers); + m_devicePath = object.value(QStringLiteral("device")).toString(); - QJsonArray outputs = object.value("outputs").toArray(); + const QJsonArray outputs = object.value(QStringLiteral("outputs")).toArray(); for (int i = 0; i < outputs.size(); i++) { - QVariantMap outputSettings = outputs.at(i).toObject().toVariantMap(); + const QVariantMap outputSettings = outputs.at(i).toObject().toVariantMap(); - if (outputSettings.contains("name")) { - QString name = outputSettings.value("name").toString(); + if (outputSettings.contains(QStringLiteral("name"))) { + const QString name = outputSettings.value(QStringLiteral("name")).toString(); if (m_outputSettings.contains(name)) { qCDebug(qLcEglfsKmsDebug) << "Output" << name << "configured multiple times!"; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp index a36ce50b76..a27819d1dd 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp @@ -303,4 +303,10 @@ void QEglFSKmsScreen::restoreMode() } } +qreal QEglFSKmsScreen::refreshRate() const +{ + quint32 refresh = m_output.modes[m_output.mode].vrefresh; + return refresh > 0 ? refresh : 60; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h index ed79d00896..16521c7fe0 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h @@ -83,6 +83,8 @@ public: QPlatformCursor *cursor() const Q_DECL_OVERRIDE; + qreal refreshRate() const Q_DECL_OVERRIDE; + QEglFSKmsDevice *device() const { return m_device; } gbm_surface *surface() const { return m_gbm_surface; } diff --git a/src/plugins/platforms/eglfs/eglfs_device_lib.pro b/src/plugins/platforms/eglfs/eglfs_device_lib.pro index d8ce421a69..729290706d 100644 --- a/src/plugins/platforms/eglfs/eglfs_device_lib.pro +++ b/src/plugins/platforms/eglfs/eglfs_device_lib.pro @@ -56,4 +56,4 @@ INCLUDEPATH += $$PWD CONFIG += egl qpa/genericunixfontdatabase -RESOURCES += $$PWD/cursor.qrc +!contains(DEFINES, QT_NO_CURSOR): RESOURCES += $$PWD/cursor.qrc diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp index 7d1007e7ef..2a46c87862 100644 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp @@ -225,6 +225,11 @@ QImage::Format QEGLDeviceIntegration::screenFormat() const return screenDepth() == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32; } +qreal QEGLDeviceIntegration::refreshRate() const +{ + return q_refreshRateFromFb(framebuffer); +} + QSurfaceFormat QEGLDeviceIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const { QSurfaceFormat format = inputFormat; diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h index 019312e755..260fc313f7 100644 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h @@ -77,6 +77,7 @@ public: virtual Qt::ScreenOrientation orientation() const; virtual int screenDepth() const; virtual QImage::Format screenFormat() const; + virtual qreal refreshRate() const; virtual QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const; virtual EGLNativeWindowType createNativeWindow(QPlatformWindow *platformWindow, const QSize &size, diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 2da47db602..d1688df8f5 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -56,7 +56,9 @@ static void initResources() { +#ifndef QT_NO_CURSOR Q_INIT_RESOURCE(cursor); +#endif } QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index cc2ee80bd3..1b6e2307f8 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -93,6 +93,11 @@ QPlatformCursor *QEglFSScreen::cursor() const return m_cursor; } +qreal QEglFSScreen::refreshRate() const +{ + return qt_egl_device_integration()->refreshRate(); +} + void QEglFSScreen::setPrimarySurface(EGLSurface surface) { m_surface = surface; diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h index 14ec9682a6..07b6ff63ef 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.h +++ b/src/plugins/platforms/eglfs/qeglfsscreen.h @@ -60,6 +60,8 @@ public: QPlatformCursor *cursor() const Q_DECL_OVERRIDE; + qreal refreshRate() const Q_DECL_OVERRIDE; + EGLSurface primarySurface() const { return m_surface; } protected: diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index 3a6b67f72e..fdaa7e68fe 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -52,7 +52,7 @@ public: void interruptEventLoopExec(); private: - uint m_processEventCallsAfterExec; + uint m_processEventLevel; RunLoopObserver<QIOSEventDispatcher> m_runLoopExitObserver; }; diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index f4567f36f4..fc12e83a81 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -422,7 +422,7 @@ QT_USE_NAMESPACE QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) : QEventDispatcherCoreFoundation(parent) - , m_processEventCallsAfterExec(0) + , m_processEventLevel(0) , m_runLoopExitObserver(this, &QIOSEventDispatcher::handleRunLoopExit, kCFRunLoopExit) { } @@ -439,8 +439,8 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo return false; } - if (!m_processEventCallsAfterExec && (flags & QEventLoop::EventLoopExec)) { - ++m_processEventCallsAfterExec; + if (!m_processEventLevel && (flags & QEventLoop::EventLoopExec)) { + ++m_processEventLevel; m_runLoopExitObserver.addToMode(kCFRunLoopCommonModes); @@ -465,13 +465,9 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo Q_UNREACHABLE(); } - if (m_processEventCallsAfterExec) - ++m_processEventCallsAfterExec; - + ++m_processEventLevel; bool processedEvents = QEventDispatcherCoreFoundation::processEvents(flags); - - if (m_processEventCallsAfterExec) - --m_processEventCallsAfterExec; + --m_processEventLevel; return processedEvents; } @@ -481,7 +477,7 @@ void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity) Q_UNUSED(activity); Q_ASSERT(activity == kCFRunLoopExit); - if (m_processEventCallsAfterExec == 1 && !QThreadData::current()->eventLoops.top()->isRunning()) { + if (m_processEventLevel == 1 && !QThreadData::current()->eventLoops.top()->isRunning()) { qEventDispatcherDebug() << "Root runloop level exited"; interruptEventLoopExec(); } @@ -489,9 +485,9 @@ void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity) void QIOSEventDispatcher::interruptEventLoopExec() { - Q_ASSERT(m_processEventCallsAfterExec == 1); + Q_ASSERT(m_processEventLevel == 1); - --m_processEventCallsAfterExec; + --m_processEventLevel; m_runLoopExitObserver.removeFromMode(kCFRunLoopCommonModes); diff --git a/src/plugins/platforms/ios/qiosfiledialog.mm b/src/plugins/platforms/ios/qiosfiledialog.mm index 1d4298a158..0e12da9d57 100644 --- a/src/plugins/platforms/ios/qiosfiledialog.mm +++ b/src/plugins/platforms/ios/qiosfiledialog.mm @@ -60,7 +60,8 @@ { Q_UNUSED(picker); NSURL *url = [info objectForKey:UIImagePickerControllerReferenceURL]; - m_fileDialog->selectedFilesChanged(QList<QUrl>() << QUrl::fromNSURL(url)); + QUrl fileUrl = QUrl::fromLocalFile(QString::fromNSString([url description])); + m_fileDialog->selectedFilesChanged(QList<QUrl>() << fileUrl); emit m_fileDialog->accept(); } @@ -94,7 +95,8 @@ bool QIOSFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality window Q_UNUSED(windowFlags); Q_UNUSED(windowModality); - if (options()->initialDirectory().scheme() == QLatin1String("assets-library")) { + QString directory = options()->initialDirectory().toLocalFile(); + if (directory.startsWith(QLatin1String("assets-library:"))) { m_viewController = [[QIOSImagePickerController alloc] initWithQIOSFileDialog:this]; UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window : [UIApplication sharedApplication].keyWindow; diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm index c4be7cf4dc..73bfc2a87f 100644 --- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm +++ b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm @@ -42,9 +42,9 @@ class QIOSAssetData : public QObject { public: - QIOSAssetData(const QString &fileName, QIOSFileEngineAssetsLibrary *engine) + QIOSAssetData(const QString &assetUrl, QIOSFileEngineAssetsLibrary *engine) : m_asset(0) - , m_fileName(fileName) + , m_assetUrl(assetUrl) , m_assetLibrary(0) { switch ([ALAssetsLibrary authorizationStatus]) { @@ -71,7 +71,7 @@ public: // reuse its data. Since QFile is (mostly) reentrant, we need to protect m_currentAssetData // from being modified by several threads at the same time. QMutexLocker lock(&g_mutex); - if (g_currentAssetData && g_currentAssetData->m_fileName == fileName) { + if (g_currentAssetData && g_currentAssetData->m_assetUrl == assetUrl) { m_assetLibrary = [g_currentAssetData->m_assetLibrary retain]; m_asset = [g_currentAssetData->m_asset retain]; return; @@ -87,7 +87,7 @@ public: dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - NSURL *url = [NSURL URLWithString:m_fileName.toNSString()]; + NSURL *url = [NSURL URLWithString:assetUrl.toNSString()]; m_assetLibrary = [[ALAssetsLibrary alloc] init]; [m_assetLibrary assetForURL:url resultBlock:^(ALAsset *asset) { m_asset = [asset retain]; @@ -117,7 +117,7 @@ public: ALAsset *m_asset; private: - QString m_fileName; + QString m_assetUrl; ALAssetsLibrary *m_assetLibrary; static QBasicMutex g_mutex; @@ -143,8 +143,18 @@ QIOSFileEngineAssetsLibrary::~QIOSFileEngineAssetsLibrary() ALAsset *QIOSFileEngineAssetsLibrary::loadAsset() const { - if (!m_data) - m_data = new QIOSAssetData(m_fileName, const_cast<QIOSFileEngineAssetsLibrary *>(this)); + if (!m_data) { + // QUrl::fromLocalFile() will remove double slashes. Since the asset url is passed around as a file + // name in the app (and converted to/from a file url, e.g in QFileDialog), we need to check if we still + // have two leading slashes after the scheme, and restore the second slash if not. + QString assetUrl = m_fileName; + const int index = 16; // "assets-library://" + if (assetUrl[index] != QLatin1Char('/')) + assetUrl.insert(index, '/'); + + m_data = new QIOSAssetData(assetUrl, const_cast<QIOSFileEngineAssetsLibrary *>(this)); + } + return m_data->m_asset; } diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 22847b0612..a558ebe1f7 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -587,28 +587,27 @@ void QIOSInputContext::update(Qt::InputMethodQueries updatedProperties) qImDebug() << "fw =" << qApp->focusWindow() << "fo =" << qApp->focusObject(); Qt::InputMethodQueries changedProperties = m_imeState.update(updatedProperties); - if (changedProperties & (Qt::ImEnabled | Qt::ImHints | Qt::ImPlatformData)) { - // Changes to enablement or hints require virtual keyboard reconfigure - - qImDebug() << "changed IM properties" << changedProperties << "require keyboard reconfigure"; + if (m_textResponder && changedProperties & (Qt::ImHints | Qt::ImPlatformData)) { + qImDebug() << "current IM state requires new text responder"; + [m_textResponder autorelease]; + m_textResponder = 0; + } - if (inputMethodAccepted()) { - qImDebug() << "replacing text responder with new text responder"; - [m_textResponder autorelease]; + if (inputMethodAccepted()) { + if (!m_textResponder) { + qImDebug() << "creating new text responder"; m_textResponder = [[QIOSTextInputResponder alloc] initWithInputContext:this]; - [m_textResponder becomeFirstResponder]; - } else if ([UIResponder currentFirstResponder] == m_textResponder) { - qImDebug() << "IM not enabled, resigning text responder as first responder"; - [m_textResponder resignFirstResponder]; - } else { - qImDebug() << "IM not enabled. Text responder not first responder. Nothing to do"; } - } else { + if (![m_textResponder isFirstResponder]) + [m_textResponder becomeFirstResponder]; + [m_textResponder notifyInputDelegate:changedProperties]; - } - if (changedProperties & Qt::ImCursorRectangle) - scrollToCursor(); + if (changedProperties & Qt::ImCursorRectangle) + scrollToCursor(); + } else if ([m_textResponder isFirstResponder]) { + [m_textResponder resignFirstResponder]; + } } bool QIOSInputContext::inputMethodAccepted() const diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 8a27342d2f..c22c43e455 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -45,8 +45,10 @@ QT_BEGIN_NAMESPACE class QIOSServices; -class QIOSIntegration : public QPlatformIntegration, public QPlatformNativeInterface +class QIOSIntegration : public QPlatformNativeInterface, public QPlatformIntegration { + Q_OBJECT + public: QIOSIntegration(); ~QIOSIntegration(); @@ -72,8 +74,6 @@ public: QAbstractEventDispatcher *createEventDispatcher() const; QPlatformNativeInterface *nativeInterface() const; - void *nativeResourceForWindow(const QByteArray &resource, QWindow *window); - QTouchDevice *touchDevice(); QPlatformAccessibility *accessibility() const Q_DECL_OVERRIDE; @@ -83,6 +83,10 @@ public: static QIOSIntegration *instance(); + // -- QPlatformNativeInterface -- + + void *nativeResourceForWindow(const QByteArray &resource, QWindow *window); + private: QPlatformFontDatabase *m_fontDatabase; QPlatformClipboard *m_clipboard; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 9d29b4edf7..fcfd6c7cc8 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -215,11 +215,25 @@ QPlatformTheme *QIOSIntegration::createPlatformTheme(const QString &name) const return QPlatformIntegration::createPlatformTheme(name); } +QTouchDevice *QIOSIntegration::touchDevice() +{ + return m_touchDevice; +} + +QPlatformAccessibility *QIOSIntegration::accessibility() const +{ + if (!m_accessibility) + m_accessibility = new QIOSPlatformAccessibility; + return m_accessibility; +} + QPlatformNativeInterface *QIOSIntegration::nativeInterface() const { return const_cast<QIOSIntegration *>(this); } +// --------------------------------------------------------- + void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window) { if (!window || !window->handle()) @@ -235,16 +249,8 @@ void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWind return 0; } -QTouchDevice *QIOSIntegration::touchDevice() -{ - return m_touchDevice; -} +// --------------------------------------------------------- -QPlatformAccessibility *QIOSIntegration::accessibility() const -{ - if (!m_accessibility) - m_accessibility = new QIOSPlatformAccessibility; - return m_accessibility; -} +#include "moc_qiosintegration.cpp" QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 02c3a2d28d..d144b419aa 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -238,7 +238,7 @@ -(BOOL)shouldAutorotate { - return m_screen->uiScreen() == [UIScreen mainScreen] && !self.lockedOrientation; + return m_screen && m_screen->uiScreen() == [UIScreen mainScreen] && !self.lockedOrientation; } #if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_6_0) diff --git a/src/plugins/platforms/windows/openglblacklists.qrc b/src/plugins/platforms/windows/openglblacklists.qrc new file mode 100644 index 0000000000..9f0c186c21 --- /dev/null +++ b/src/plugins/platforms/windows/openglblacklists.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/qt-project.org/windows/openglblacklists"> + <file alias="default.json">openglblacklists/default.json</file> + </qresource> +</RCC> diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json new file mode 100644 index 0000000000..0217b79ecf --- /dev/null +++ b/src/plugins/platforms/windows/openglblacklists/default.json @@ -0,0 +1,18 @@ +{ + "name": "Qt built-in GPU driver blacklist", + "version": "5.5", + "entries": [ + { + "id": 1, + "description": "Desktop OpenGL is unreliable on Intel HD3000/GMA (QTBUG-43263, QTBUG-42240)", + "vendor_id": "0x8086", + "device_id": [ "0x0A16" ], + "os": { + "type": "win" + }, + "features": [ + "disable_desktopgl" + ] + } + ] +} diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index ebd41d482b..fa355f6201 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -173,7 +173,7 @@ static inline QWindowsSessionManager *platformSessionManager() { QWindowsUser32DLL::QWindowsUser32DLL() : setLayeredWindowAttributes(0), updateLayeredWindow(0), updateLayeredWindowIndirect(0), - isHungAppWindow(0), + isHungAppWindow(0), isTouchWindow(0), registerTouchWindow(0), unregisterTouchWindow(0), getTouchInputInfo(0), closeTouchInputHandle(0), setProcessDPIAware(0), addClipboardFormatListener(0), removeClipboardFormatListener(0) @@ -202,11 +202,12 @@ void QWindowsUser32DLL::init() bool QWindowsUser32DLL::initTouch() { QSystemLibrary library(QStringLiteral("user32")); + isTouchWindow = (IsTouchWindow)(library.resolve("IsTouchWindow")); registerTouchWindow = (RegisterTouchWindow)(library.resolve("RegisterTouchWindow")); unregisterTouchWindow = (UnregisterTouchWindow)(library.resolve("UnregisterTouchWindow")); getTouchInputInfo = (GetTouchInputInfo)(library.resolve("GetTouchInputInfo")); closeTouchInputHandle = (CloseTouchInputHandle)(library.resolve("CloseTouchInputHandle")); - return registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && closeTouchInputHandle; + return isTouchWindow && registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && closeTouchInputHandle; } /*! diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 870a42946d..81f4a36433 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -76,6 +76,7 @@ struct QWindowsUser32DLL inline void init(); inline bool initTouch(); + typedef BOOL (WINAPI *IsTouchWindow)(HWND, PULONG); typedef BOOL (WINAPI *RegisterTouchWindow)(HWND, ULONG); typedef BOOL (WINAPI *UnregisterTouchWindow)(HWND); typedef BOOL (WINAPI *GetTouchInputInfo)(HANDLE, UINT, PVOID, int); @@ -99,6 +100,7 @@ struct QWindowsUser32DLL IsHungAppWindow isHungAppWindow; // Touch functions from Windows 7 onwards (also for use with Q_CC_MSVC). + IsTouchWindow isTouchWindow; RegisterTouchWindow registerTouchWindow; UnregisterTouchWindow unregisterTouchWindow; GetTouchInputInfo getTouchInputInfo; diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index 74efd49217..7db6abd8ef 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -416,12 +416,15 @@ QWindowsOpenGLContext *QWindowsEGLStaticContext::createContext(QOpenGLContext *c return new QWindowsEGLContext(this, context->format(), context->shareHandle()); } -void *QWindowsEGLStaticContext::createWindowSurface(void *nativeWindow, void *nativeConfig) +void *QWindowsEGLStaticContext::createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) { + *err = 0; EGLSurface surface = libEGL.eglCreateWindowSurface(m_display, (EGLConfig) nativeConfig, (EGLNativeWindowType) nativeWindow, 0); - if (surface == EGL_NO_SURFACE) - qWarning("%s: Could not create the EGL window surface: 0x%x\n", Q_FUNC_INFO, libEGL.eglGetError()); + if (surface == EGL_NO_SURFACE) { + *err = libEGL.eglGetError(); + qWarning("%s: Could not create the EGL window surface: 0x%x\n", Q_FUNC_INFO, *err); + } return surface; } @@ -578,8 +581,15 @@ bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface) QWindowsWindow *window = static_cast<QWindowsWindow *>(surface); window->aboutToMakeCurrent(); - EGLSurface eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig)); - Q_ASSERT(eglSurface); + int err = 0; + EGLSurface eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig, &err)); + if (eglSurface == EGL_NO_SURFACE) { + if (err == EGL_CONTEXT_LOST) { + m_eglContext = EGL_NO_CONTEXT; + qCDebug(lcQpaGl) << "Got EGL context lost in createWindowSurface() for context" << this; + } + return false; + } // shortcut: on some GPUs, eglMakeCurrent is not a cheap operation if (QWindowsEGLStaticContext::libEGL.eglGetCurrentContext() == m_eglContext && @@ -597,7 +607,7 @@ bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface) QWindowsEGLStaticContext::libEGL.eglSwapInterval(m_staticContext->display(), m_swapInterval); } } else { - int err = QWindowsEGLStaticContext::libEGL.eglGetError(); + err = QWindowsEGLStaticContext::libEGL.eglGetError(); // EGL_CONTEXT_LOST (loss of the D3D device) is not necessarily fatal. // Qt Quick is able to recover for example. if (err == EGL_CONTEXT_LOST) { @@ -625,8 +635,15 @@ void QWindowsEGLContext::swapBuffers(QPlatformSurface *surface) { QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api); QWindowsWindow *window = static_cast<QWindowsWindow *>(surface); - EGLSurface eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig)); - Q_ASSERT(eglSurface); + int err = 0; + EGLSurface eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig, &err)); + if (eglSurface == EGL_NO_SURFACE) { + if (err == EGL_CONTEXT_LOST) { + m_eglContext = EGL_NO_CONTEXT; + qCDebug(lcQpaGl) << "Got EGL context lost in createWindowSurface() for context" << this; + } + return; + } bool ok = QWindowsEGLStaticContext::libEGL.eglSwapBuffers(m_eglDisplay, eglSurface); if (!ok) diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h index 55f58fac5f..2b249348c3 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.h +++ b/src/plugins/platforms/windows/qwindowseglcontext.h @@ -260,7 +260,7 @@ public: void *moduleHandle() const { return libGLESv2.moduleHandle(); } QOpenGLContext::OpenGLModuleType moduleType() const { return QOpenGLContext::LibGLES; } - void *createWindowSurface(void *nativeWindow, void *nativeConfig) Q_DECL_OVERRIDE; + void *createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) Q_DECL_OVERRIDE; void destroyWindowSurface(void *nativeSurface) Q_DECL_OVERRIDE; QSurfaceFormat formatFromConfig(EGLDisplay display, EGLConfig config, const QSurfaceFormat &referenceFormat); diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index d1ea8a798f..ad75a0bd54 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -336,7 +336,8 @@ static bool addFontToDatabase(const QString &faceName, uchar charSet, const TEXTMETRIC *textmetric, const FONTSIGNATURE *signature, - int type) + int type, + bool registerAlias) { // the "@family" fonts are just the same as "family". Ignore them. if (faceName.isEmpty() || faceName.at(0) == QLatin1Char('@') || faceName.startsWith(QLatin1String("WST_"))) @@ -373,7 +374,7 @@ static bool addFontToDatabase(const QString &faceName, #endif QString englishName; - if (ttf && localizedName(faceName)) + if (registerAlias & ttf && localizedName(faceName)) englishName = getEnglishName(faceName); QSupportedWritingSystems writingSystems; @@ -467,64 +468,23 @@ static QByteArray getFntTable(HFONT hfont, uint tag) #endif static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, - int type, LPARAM namesSetIn) + int type, LPARAM) { - typedef QSet<QString> StringSet; const QString faceName = QString::fromWCharArray(f->elfLogFont.lfFaceName); const QString fullName = QString::fromWCharArray(f->elfFullName); const uchar charSet = f->elfLogFont.lfCharSet; -#ifndef Q_OS_WINCE const FONTSIGNATURE signature = textmetric->ntmFontSig; -#else - FONTSIGNATURE signature; - QByteArray table; - - if (type & TRUETYPE_FONTTYPE) { - HFONT hfont = CreateFontIndirect(&f->elfLogFont); - table = getFntTable(hfont, MAKE_TAG('O', 'S', '/', '2')); - DeleteObject((HGDIOBJ)hfont); - } - - if (table.length() >= 86) { - // See also qfontdatabase_mac.cpp, offsets taken from OS/2 table in the TrueType spec - uchar *tableData = reinterpret_cast<uchar *>(table.data()); - - signature.fsUsb[0] = qFromBigEndian<quint32>(tableData + 42); - signature.fsUsb[1] = qFromBigEndian<quint32>(tableData + 46); - signature.fsUsb[2] = qFromBigEndian<quint32>(tableData + 50); - signature.fsUsb[3] = qFromBigEndian<quint32>(tableData + 54); - - signature.fsCsb[0] = qFromBigEndian<quint32>(tableData + 78); - signature.fsCsb[1] = qFromBigEndian<quint32>(tableData + 82); - } else { - memset(&signature, 0, sizeof(signature)); - } -#endif - // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is // identical to a TEXTMETRIC except for the last four members, which we don't use // anyway - if (addFontToDatabase(faceName, fullName, - charSet, (TEXTMETRIC *)textmetric, &signature, type)) { - reinterpret_cast<StringSet *>(namesSetIn)->insert(faceName + QStringLiteral("::") + fullName); - } + addFontToDatabase(faceName, fullName, charSet, (TEXTMETRIC *)textmetric, &signature, type, false); // keep on enumerating return 1; } -void QWindowsFontDatabaseFT::populateFontDatabase() -{ - m_families.clear(); - populate(); // Called multiple times. - // Work around EnumFontFamiliesEx() not listing the system font, see below. - const QString sysFontFamily = QGuiApplication::font().family(); - if (!m_families.contains(sysFontFamily)) - populate(sysFontFamily); -} - /*! \brief Populate font database using EnumFontFamiliesEx(). @@ -533,29 +493,157 @@ void QWindowsFontDatabaseFT::populateFontDatabase() are only found when specifying the name explicitly. */ -void QWindowsFontDatabaseFT::populate(const QString &family) - { - - qCDebug(lcQpaFonts) << __FUNCTION__ << m_families.size() << family; - +void QWindowsFontDatabaseFT::populateFamily(const QString &familyName) +{ + qCDebug(lcQpaFonts) << familyName; + if (familyName.size() >= LF_FACESIZE) { + qCWarning(lcQpaFonts) << "Unable to enumerate family '" << familyName << '\''; + return; + } HDC dummy = GetDC(0); LOGFONT lf; lf.lfCharSet = DEFAULT_CHARSET; - if (family.size() >= LF_FACESIZE) { - qWarning("%s: Unable to enumerate family '%s'.", - __FUNCTION__, qPrintable(family)); - return; + familyName.toWCharArray(lf.lfFaceName); + lf.lfFaceName[familyName.size()] = 0; + lf.lfPitchAndFamily = 0; + EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont, 0, 0); + ReleaseDC(0, dummy); +} + +namespace { +// Context for enumerating system fonts, records whether the default font has been +// encountered, which is normally not enumerated. +struct PopulateFamiliesContext +{ + PopulateFamiliesContext(const QString &f) : systemDefaultFont(f), seenSystemDefaultFont(false) {} + + QString systemDefaultFont; + bool seenSystemDefaultFont; +}; +} // namespace + +#ifndef Q_OS_WINCE + +// Delayed population of font families + +static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *tm, int, LPARAM lparam) +{ + // the "@family" fonts are just the same as "family". Ignore them. + const wchar_t *faceNameW = f->elfLogFont.lfFaceName; + if (faceNameW[0] && faceNameW[0] != L'@' && wcsncmp(faceNameW, L"WST_", 4)) { + // Register only font families for which a font file exists for delayed population + const QString faceName = QString::fromWCharArray(faceNameW); + const FontKey *key = findFontKey(faceName); + if (!key) { + key = findFontKey(QString::fromWCharArray(f->elfFullName)); + if (!key && (tm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE) && localizedName(faceName)) + key = findFontKey(getEnglishName(faceName)); + } + if (key) { + QPlatformFontDatabase::registerFontFamily(faceName); + PopulateFamiliesContext *context = reinterpret_cast<PopulateFamiliesContext *>(lparam); + if (!context->seenSystemDefaultFont && faceName == context->systemDefaultFont) + context->seenSystemDefaultFont = true; + + // Register current font's english name as alias + const bool ttf = (tm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE); + if (ttf && localizedName(faceName)) { + const QString englishName = getEnglishName(faceName); + if (!englishName.isEmpty()) { + QPlatformFontDatabase::registerAliasToFontFamily(faceName, englishName); + // Check whether the system default font name is an alias of the current font family name, + // as on Chinese Windows, where the system font "SimSun" is an alias to a font registered under a local name + if (!context->seenSystemDefaultFont && englishName == context->systemDefaultFont) + context->seenSystemDefaultFont = true; + } + } + } } + return 1; // continue +} - wmemcpy(lf.lfFaceName, reinterpret_cast<const wchar_t*>(family.utf16()), - family.size() + 1); +void QWindowsFontDatabaseFT::populateFontDatabase() +{ + HDC dummy = GetDC(0); + LOGFONT lf; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfFaceName[0] = 0; lf.lfPitchAndFamily = 0; + PopulateFamiliesContext context(QWindowsFontDatabase::systemDefaultFont().family()); + EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0); + ReleaseDC(0, dummy); + // Work around EnumFontFamiliesEx() not listing the system font + if (!context.seenSystemDefaultFont) + QPlatformFontDatabase::registerFontFamily(context.systemDefaultFont); +} + +#else // !Q_OS_WINCE + +// Non-delayed population of fonts (Windows CE). + +static int QT_WIN_CALLBACK populateFontCe(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, + int type, LPARAM lparam) +{ + // the "@family" fonts are just the same as "family". Ignore them. + const wchar_t *faceNameW = f->elfLogFont.lfFaceName; + if (faceNameW[0] && faceNameW[0] != L'@' && wcsncmp(faceNameW, L"WST_", 4)) { + const uchar charSet = f->elfLogFont.lfCharSet; + + FONTSIGNATURE signature; + QByteArray table; + + if (type & TRUETYPE_FONTTYPE) { + HFONT hfont = CreateFontIndirect(&f->elfLogFont); + table = getFntTable(hfont, MAKE_TAG('O', 'S', '/', '2')); + DeleteObject((HGDIOBJ)hfont); + } + + if (table.length() >= 86) { + // See also qfontdatabase_mac.cpp, offsets taken from OS/2 table in the TrueType spec + uchar *tableData = reinterpret_cast<uchar *>(table.data()); + + signature.fsUsb[0] = qFromBigEndian<quint32>(tableData + 42); + signature.fsUsb[1] = qFromBigEndian<quint32>(tableData + 46); + signature.fsUsb[2] = qFromBigEndian<quint32>(tableData + 50); + signature.fsUsb[3] = qFromBigEndian<quint32>(tableData + 54); + + signature.fsCsb[0] = qFromBigEndian<quint32>(tableData + 78); + signature.fsCsb[1] = qFromBigEndian<quint32>(tableData + 82); + } else { + memset(&signature, 0, sizeof(signature)); + } - EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont, - (LPARAM)&m_families, 0); + // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is + // identical to a TEXTMETRIC except for the last four members, which we don't use + // anyway + const QString faceName = QString::fromWCharArray(f->elfLogFont.lfFaceName); + if (addFontToDatabase(faceName, QString::fromWCharArray(f->elfFullName), + charSet, (TEXTMETRIC *)textmetric, &signature, type, true)) { + PopulateFamiliesContext *context = reinterpret_cast<PopulateFamiliesContext *>(lparam); + if (!context->seenSystemDefaultFont && faceName == context->systemDefaultFont) + context->seenSystemDefaultFont = true; + } + } + // keep on enumerating + return 1; +} + +void QWindowsFontDatabaseFT::populateFontDatabase() +{ + LOGFONT lf; + lf.lfCharSet = DEFAULT_CHARSET; + HDC dummy = GetDC(0); + lf.lfFaceName[0] = 0; + lf.lfPitchAndFamily = 0; + PopulateFamiliesContext context(QWindowsFontDatabase::systemDefaultFont().family()); + EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)populateFontCe, reinterpret_cast<LPARAM>(&context), 0); ReleaseDC(0, dummy); + // Work around EnumFontFamiliesEx() not listing the system font, see below. + if (!context.seenSystemDefaultFont) + populateFamily(context.systemDefaultFont); } +#endif // Q_OS_WINCE QFontEngine * QWindowsFontDatabaseFT::fontEngine(const QFontDef &fontDef, void *handle) { @@ -592,7 +680,7 @@ QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString &family, QF result.append(QWindowsFontDatabase::extraTryFontsForFamily(family)); qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint - << script << result << m_families; + << script << result; return result; } diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h index 7552458a9f..ad5c005ffa 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h @@ -44,6 +44,7 @@ class QWindowsFontDatabaseFT : public QBasicFontDatabase { public: void populateFontDatabase(); + void populateFamily(const QString &familyName) Q_DECL_OVERRIDE; QFontEngine *fontEngine(const QFontDef &fontDef, void *handle); QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); @@ -51,11 +52,6 @@ public: QString fontDir() const Q_DECL_OVERRIDE; QFont defaultFont() const Q_DECL_OVERRIDE; - -private: - void populate(const QString &family = QString()); - - QSet<QString> m_families; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index ca28b822e4..c25b90e98c 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -194,10 +194,10 @@ void QWindowsFontEngine::getCMap() _faceId.index = 0; if(cmap) { OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc); - designToDevice = QFixed((int)otm->otmEMSquare)/int(otm->otmTextMetrics.tmHeight); + designToDevice = QFixed((int)otm->otmEMSquare)/QFixed::fromReal(fontDef.pixelSize); unitsPerEm = otm->otmEMSquare; x_height = (int)otm->otmsXHeight; - loadKerningPairs(designToDevice); + loadKerningPairs(QFixed((int)otm->otmEMSquare)/int(otm->otmTextMetrics.tmHeight)); _faceId.filename = QFile::encodeName(QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFullName))); lineWidth = otm->otmsUnderscoreSize; fsType = otm->otmfsType; @@ -361,7 +361,7 @@ glyph_t QWindowsFontEngine::glyphIndex(uint ucs4) const HGDIOBJ QWindowsFontEngine::selectDesignFont() const { LOGFONT f = m_logfont; - f.lfHeight = unitsPerEm; + f.lfHeight = -unitsPerEm; f.lfWidth = 0; HFONT designFont = CreateFontIndirect(&f); return SelectObject(m_fontEngineData->hdc, designFont); diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 9fd18a1ef4..1041ecf44d 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -79,9 +79,7 @@ # include "qwindowsglcontext.h" #endif -#ifndef Q_OS_WINCE -# include "qwindowsopengltester.h" -#endif +#include "qwindowsopengltester.h" QT_BEGIN_NAMESPACE @@ -209,6 +207,10 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList ¶mL : m_options(0) , m_fontDatabase(0) { +#ifndef Q_OS_WINCE + Q_INIT_RESOURCE(openglblacklists); +#endif + static bool dpiAwarenessSet = false; int tabletAbsoluteRange = -1; // Default to per-monitor awareness to avoid being scaled when monitors with different DPI diff --git a/src/plugins/platforms/windows/qwindowsopenglcontext.h b/src/plugins/platforms/windows/qwindowsopenglcontext.h index 8ebcb83a08..2c52c58829 100644 --- a/src/plugins/platforms/windows/qwindowsopenglcontext.h +++ b/src/plugins/platforms/windows/qwindowsopenglcontext.h @@ -56,7 +56,7 @@ public: // If the windowing system interface needs explicitly created window surfaces (like EGL), // reimplement these. - virtual void *createWindowSurface(void * /*nativeWindow*/, void * /*nativeConfig*/) { return 0; } + virtual void *createWindowSurface(void * /*nativeWindow*/, void * /*nativeConfig*/, int * /*err*/) { return 0; } virtual void destroyWindowSurface(void * /*nativeSurface*/) { } private: diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index ba4c95544e..67548a0836 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -42,14 +42,16 @@ #include <QtCore/QFileInfo> #include <QtCore/QStandardPaths> #include <QtCore/QLibraryInfo> +#include <QtCore/QHash> +#ifndef QT_NO_OPENGL #include <private/qopengl_p.h> +#endif #ifndef Q_OS_WINCE # include <QtCore/qt_windows.h> # include <private/qsystemlibrary_p.h> # include <d3d9.h> -# include <GL/gl.h> #endif QT_BEGIN_NAMESPACE @@ -206,56 +208,62 @@ static inline QString resolveBugListFile(const QString &fileName) return QStandardPaths::locate(QStandardPaths::ConfigLocation, fileName); } -static void readDriverBugList(const GpuDescription &gpu, - QWindowsOpenGLTester::Renderers *result) +typedef QHash<QOpenGLConfig::Gpu, QWindowsOpenGLTester::Renderers> SupportedRenderersCache; +Q_GLOBAL_STATIC(SupportedRenderersCache, supportedRenderersCache) + +#endif // !Q_OS_WINCE + +QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(const GpuDescription &gpu, bool glesOnly) { - const char bugListFileVar[] = "QT_OPENGL_BUGLIST"; - if (!qEnvironmentVariableIsSet(bugListFileVar)) - return; - const QString fileName = resolveBugListFile(QFile::decodeName(qgetenv(bugListFileVar))); - if (fileName.isEmpty()) - return; + Q_UNUSED(gpu) +#ifndef Q_OS_WINCE QOpenGLConfig::Gpu qgpu; qgpu.deviceId = gpu.deviceId; qgpu.vendorId = gpu.vendorId; qgpu.driverVersion = gpu.driverVersion; - const QSet<QString> features = QOpenGLConfig::gpuFeatures(qgpu, fileName); + SupportedRenderersCache *srCache = supportedRenderersCache(); + SupportedRenderersCache::const_iterator it = srCache->find(qgpu); + if (it != srCache->cend()) + return *it; + + QWindowsOpenGLTester::Renderers result(QWindowsOpenGLTester::AngleRendererD3d11 + | QWindowsOpenGLTester::AngleRendererD3d9 + | QWindowsOpenGLTester::AngleRendererD3d11Warp + | QWindowsOpenGLTester::SoftwareRasterizer); + + if (!glesOnly && testDesktopGL()) + result |= QWindowsOpenGLTester::DesktopGl; + + QSet<QString> features; + const char bugListFileVar[] = "QT_OPENGL_BUGLIST"; + if (qEnvironmentVariableIsSet(bugListFileVar)) { + const QString fileName = resolveBugListFile(QFile::decodeName(qgetenv(bugListFileVar))); + if (!fileName.isEmpty()) + features = QOpenGLConfig::gpuFeatures(qgpu, fileName); + } else { + features = QOpenGLConfig::gpuFeatures(qgpu, QStringLiteral(":/qt-project.org/windows/openglblacklists/default.json")); + } + qCDebug(lcQpaGl) << "GPU features:" << features; + if (features.contains(QStringLiteral("disable_desktopgl"))) { // Qt-specific qCWarning(lcQpaGl) << "Disabling Desktop GL: " << gpu; - *result &= ~QWindowsOpenGLTester::DesktopGl; + result &= ~QWindowsOpenGLTester::DesktopGl; } if (features.contains(QStringLiteral("disable_angle"))) { // Qt-specific keyword qCWarning(lcQpaGl) << "Disabling ANGLE: " << gpu; - *result &= ~QWindowsOpenGLTester::GlesMask; + result &= ~QWindowsOpenGLTester::GlesMask; } else { if (features.contains(QStringLiteral("disable_d3d11"))) { // standard keyword qCWarning(lcQpaGl) << "Disabling D3D11: " << gpu; - *result &= ~QWindowsOpenGLTester::AngleRendererD3d11; + result &= ~QWindowsOpenGLTester::AngleRendererD3d11; } if (features.contains(QStringLiteral("disable_d3d9"))) { // Qt-specific qCWarning(lcQpaGl) << "Disabling D3D9: " << gpu; - *result &= ~QWindowsOpenGLTester::AngleRendererD3d9; + result &= ~QWindowsOpenGLTester::AngleRendererD3d9; } } -} -#endif // !Q_OS_WINCE - -static inline QWindowsOpenGLTester::Renderers - detectSupportedRenderers(const GpuDescription &gpu, bool glesOnly) -{ - Q_UNUSED(gpu) -#ifndef Q_OS_WINCE - // Add checks for card types with known issues here. - QWindowsOpenGLTester::Renderers result(QWindowsOpenGLTester::AngleRendererD3d11 - | QWindowsOpenGLTester::AngleRendererD3d9 - | QWindowsOpenGLTester::AngleRendererD3d11Warp - | QWindowsOpenGLTester::SoftwareRasterizer); - - if (!glesOnly && QWindowsOpenGLTester::testDesktopGL()) - result |= QWindowsOpenGLTester::DesktopGl; - - readDriverBugList(gpu, &result); + srCache->insert(qgpu, result); return result; #else // !Q_OS_WINCE return QWindowsOpenGLTester::Gles; diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h index 7b6164946e..748885542d 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.h +++ b/src/plugins/platforms/windows/qwindowsopengltester.h @@ -80,9 +80,12 @@ public: static Renderer requestedGlesRenderer(); static Renderer requestedRenderer(); + static Renderers supportedGlesRenderers(); static Renderers supportedRenderers(); +private: + static QWindowsOpenGLTester::Renderers detectSupportedRenderers(const GpuDescription &gpu, bool glesOnly); static bool testDesktopGL(); }; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 4cf8fcf4da..2fd0f12c26 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -2259,14 +2259,14 @@ void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins) } } -void *QWindowsWindow::surface(void *nativeConfig) +void *QWindowsWindow::surface(void *nativeConfig, int *err) { #ifdef QT_NO_OPENGL return 0; #else if (!m_surface) { if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext()) - m_surface = staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig); + m_surface = staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig, err); } return m_surface; @@ -2294,6 +2294,12 @@ void QWindowsWindow::registerTouchWindow(QWindowsWindowFunctions::TouchWindowTou #ifndef Q_OS_WINCE if ((QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch) && window()->type() != Qt::ForeignWindow) { + ULONG touchFlags = 0; + const bool ret = QWindowsContext::user32dll.isTouchWindow(m_data.hwnd, &touchFlags); + // Return if it is not a touch window or the flags are already set by a hook + // such as HCBT_CREATEWND + if (!ret || touchFlags != 0) + return; if (QWindowsContext::user32dll.registerTouchWindow(m_data.hwnd, (ULONG)touchTypes)) setFlag(TouchRegistered); else diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index f0b04fbc47..0089ad07a0 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -248,7 +248,7 @@ public: bool isEnabled() const; void setWindowIcon(const QIcon &icon); - void *surface(void *nativeConfig); + void *surface(void *nativeConfig, int *err); void invalidateSurface() Q_DECL_OVERRIDE; void aboutToMakeCurrent(); diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index 246598677f..e3880a2646 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -118,71 +118,15 @@ contains(QT_CONFIG,dynamicgl) { RESOURCES += $$PWD/cursors.qrc } +!wince*: RESOURCES += $$PWD/openglblacklists.qrc + contains(QT_CONFIG, freetype) { DEFINES *= QT_NO_FONTCONFIG - QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype - + include($$QT_SOURCE_TREE/src/3rdparty/freetype.pri) HEADERS += \ $$PWD/qwindowsfontdatabase_ft.h SOURCES += \ - $$PWD/qwindowsfontdatabase_ft.cpp \ - $$QT_FREETYPE_DIR/src/base/ftbase.c \ - $$QT_FREETYPE_DIR/src/base/ftbbox.c \ - $$QT_FREETYPE_DIR/src/base/ftdebug.c \ - $$QT_FREETYPE_DIR/src/base/ftglyph.c \ - $$QT_FREETYPE_DIR/src/base/ftinit.c \ - $$QT_FREETYPE_DIR/src/base/ftmm.c \ - $$QT_FREETYPE_DIR/src/base/fttype1.c \ - $$QT_FREETYPE_DIR/src/base/ftsynth.c \ - $$QT_FREETYPE_DIR/src/base/ftbitmap.c \ - $$QT_FREETYPE_DIR/src/bdf/bdf.c \ - $$QT_FREETYPE_DIR/src/cache/ftcache.c \ - $$QT_FREETYPE_DIR/src/cff/cff.c \ - $$QT_FREETYPE_DIR/src/cid/type1cid.c \ - $$QT_FREETYPE_DIR/src/gzip/ftgzip.c \ - $$QT_FREETYPE_DIR/src/pcf/pcf.c \ - $$QT_FREETYPE_DIR/src/pfr/pfr.c \ - $$QT_FREETYPE_DIR/src/psaux/psaux.c \ - $$QT_FREETYPE_DIR/src/pshinter/pshinter.c \ - $$QT_FREETYPE_DIR/src/psnames/psmodule.c \ - $$QT_FREETYPE_DIR/src/raster/raster.c \ - $$QT_FREETYPE_DIR/src/sfnt/sfnt.c \ - $$QT_FREETYPE_DIR/src/smooth/smooth.c \ - $$QT_FREETYPE_DIR/src/truetype/truetype.c \ - $$QT_FREETYPE_DIR/src/type1/type1.c \ - $$QT_FREETYPE_DIR/src/type42/type42.c \ - $$QT_FREETYPE_DIR/src/winfonts/winfnt.c \ - $$QT_FREETYPE_DIR/src/lzw/ftlzw.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvalid.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvbase.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvgdef.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvjstf.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvcommn.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvgpos.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvgsub.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvmod.c\ - $$QT_FREETYPE_DIR/src/autofit/afangles.c\ - $$QT_FREETYPE_DIR/src/autofit/afglobal.c\ - $$QT_FREETYPE_DIR/src/autofit/aflatin.c\ - $$QT_FREETYPE_DIR/src/autofit/afmodule.c\ - $$QT_FREETYPE_DIR/src/autofit/afdummy.c\ - $$QT_FREETYPE_DIR/src/autofit/afhints.c\ - $$QT_FREETYPE_DIR/src/autofit/afloader.c\ - $$QT_FREETYPE_DIR/src/autofit/autofit.c - - SOURCES += $$QT_FREETYPE_DIR/src/base/ftsystem.c - - - INCLUDEPATH += \ - $$QT_FREETYPE_DIR/src \ - $$QT_FREETYPE_DIR/include - - TR_EXCLUDE += $$QT_FREETYPE_DIR/* - - DEFINES += FT2_BUILD_LIBRARY - contains(QT_CONFIG, system-zlib) { - DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB - } + $$PWD/qwindowsfontdatabase_ft.cpp } else:contains(QT_CONFIG, system-freetype) { include($$QT_SOURCE_TREE/src/platformsupport/fontdatabases/basic/basic.pri) HEADERS += \ diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp index d4f1c6ae48..2c0a7a11cc 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -97,7 +97,7 @@ protected: that->format_atoms = m_clipboard->getDataInFormat(modeAtom, m_clipboard->atom(QXcbAtom::TARGETS)); if (format_atoms.size() > 0) { - xcb_atom_t *targets = (xcb_atom_t *) format_atoms.data(); + const xcb_atom_t *targets = (const xcb_atom_t *) format_atoms.data(); int size = format_atoms.size() / sizeof(xcb_atom_t); for (int i = 0; i < size; ++i) { @@ -128,7 +128,7 @@ protected: (void)formats(); // trigger update of format list QVector<xcb_atom_t> atoms; - xcb_atom_t *targets = (xcb_atom_t *) format_atoms.data(); + const xcb_atom_t *targets = (const xcb_atom_t *) format_atoms.data(); int size = format_atoms.size() / sizeof(xcb_atom_t); atoms.reserve(size); for (int i = 0; i < size; ++i) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 7ec5851737..11ff313144 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -51,6 +51,7 @@ #include <QAbstractEventDispatcher> #include <QTimer> #include <QByteArray> +#include <QScopedPointer> #include <algorithm> @@ -116,8 +117,29 @@ static int ioErrorHandler(Display *dpy) } #endif -QXcbScreen* QXcbConnection::findOrCreateScreen(QList<QXcbScreen *>& newScreens, - int screenNumber, xcb_screen_t* xcbScreen, xcb_randr_get_output_info_reply_t *output) +QXcbScreen* QXcbConnection::findScreenForCrtc(xcb_window_t rootWindow, xcb_randr_crtc_t crtc) +{ + foreach (QXcbScreen *screen, m_screens) { + if (screen->root() == rootWindow && screen->crtc() == crtc) + return screen; + } + + return 0; +} + +QXcbScreen* QXcbConnection::findScreenForOutput(xcb_window_t rootWindow, xcb_randr_output_t output) +{ + foreach (QXcbScreen *screen, m_screens) { + if (screen->root() == rootWindow && screen->output() == output) + return screen; + } + + return 0; +} + +QXcbScreen* QXcbConnection::createScreen(int screenNumber, xcb_screen_t* xcbScreen, + xcb_randr_output_t outputId, + xcb_randr_get_output_info_reply_t *output) { QString name; if (output) @@ -130,23 +152,147 @@ QXcbScreen* QXcbConnection::findOrCreateScreen(QList<QXcbScreen *>& newScreens, displayName.truncate(dotPos); name = QString::fromLocal8Bit(displayName) + QLatin1Char('.') + QString::number(screenNumber); } - foreach (QXcbScreen* scr, m_screens) - if (scr->name() == name && scr->root() == xcbScreen->root) - return scr; - QXcbScreen *ret = new QXcbScreen(this, xcbScreen, output, name, screenNumber); - newScreens << ret; - return ret; + + return new QXcbScreen(this, xcbScreen, outputId, output, name, screenNumber); +} + +bool QXcbConnection::checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output) +{ + xcb_generic_error_t *error = 0; + xcb_randr_get_output_primary_cookie_t primaryCookie = + xcb_randr_get_output_primary(xcb_connection(), rootWindow); + QScopedPointer<xcb_randr_get_output_primary_reply_t, QScopedPointerPodDeleter> primary ( + xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error)); + if (!primary || error) { + qWarning("failed to get the primary output of the screen"); + free(error); + error = NULL; + } + const bool isPrimary = primary ? (primary->output == output) : false; + + return isPrimary; +} + +xcb_screen_t* QXcbConnection::xcbScreenForRootWindow(xcb_window_t rootWindow, int *xcbScreenNumber) +{ + xcb_screen_iterator_t xcbScreenIter = xcb_setup_roots_iterator(m_setup); + for (; xcbScreenIter.rem; xcb_screen_next(&xcbScreenIter)) { + if (xcbScreenIter.data->root == rootWindow) { + if (xcbScreenNumber) + *xcbScreenNumber = xcb_setup_roots_length(m_setup) - xcbScreenIter.rem; + return xcbScreenIter.data; + } + } + + return 0; } /*! \brief Synchronizes the screen list, adds new screens, removes deleted ones */ -void QXcbConnection::updateScreens() +void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) +{ + if (event->subCode == XCB_RANDR_NOTIFY_CRTC_CHANGE) { + xcb_randr_crtc_change_t crtc = event->u.cc; + xcb_screen_t *xcbScreen = xcbScreenForRootWindow(crtc.window); + if (!xcbScreen) + // Not for us + return; + + qCDebug(lcQpaScreen) << "QXcbConnection: XCB_RANDR_NOTIFY_CRTC_CHANGE:" << crtc.crtc; + QXcbScreen *screen = findScreenForCrtc(crtc.window, crtc.crtc); + // Only update geometry when there's a valid mode on the CRTC + // CRTC with node mode could mean that output has been disabled, and we'll + // get RRNotifyOutputChange notification for that. + if (screen && crtc.mode) { + screen->updateGeometry(QRect(crtc.x, crtc.y, crtc.width, crtc.height), crtc.rotation); + if (screen->mode() != crtc.mode) + screen->updateRefreshRate(crtc.mode); + } + + } else if (event->subCode == XCB_RANDR_NOTIFY_OUTPUT_CHANGE) { + xcb_randr_output_change_t output = event->u.oc; + int xcbScreenNumber = 0; + xcb_screen_t *xcbScreen = xcbScreenForRootWindow(output.window, &xcbScreenNumber); + if (!xcbScreen) + // Not for us + return; + + QXcbScreen *screen = findScreenForOutput(output.window, output.output); + qCDebug(lcQpaScreen) << "QXcbConnection: XCB_RANDR_NOTIFY_OUTPUT_CHANGE:" << output.output; + + if (screen && output.connection == XCB_RANDR_CONNECTION_DISCONNECTED) { + qCDebug(lcQpaScreen) << "screen" << screen->name() << "has been disconnected"; + + // Known screen removed -> delete it + m_screens.removeOne(screen); + foreach (QXcbScreen *otherScreen, m_screens) + otherScreen->removeVirtualSibling((QPlatformScreen *) screen); + + QXcbIntegration::instance()->destroyScreen(screen); + + // QTBUG-40174, QTBUG-42985: If there are no outputs, then there must be + // no QScreen instances; a Qt application can survive this situation, and + // start rendering again later when there is a screen again. + + } else if (!screen && output.connection == XCB_RANDR_CONNECTION_CONNECTED) { + // New XRandR output is available and it's enabled + if (output.crtc != XCB_NONE && output.mode != XCB_NONE) { + xcb_randr_get_output_info_cookie_t outputInfoCookie = + xcb_randr_get_output_info(xcb_connection(), output.output, output.config_timestamp); + QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> outputInfo( + xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL)); + + screen = createScreen(xcbScreenNumber, xcbScreen, output.output, outputInfo.data()); + qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled"; + + screen->setPrimary(checkOutputIsPrimary(output.window, output.output)); + foreach (QXcbScreen *otherScreen, m_screens) + if (otherScreen->root() == output.window) + otherScreen->addVirtualSibling(screen); + m_screens << screen; + QXcbIntegration::instance()->screenAdded(screen, screen->isPrimary()); + } + // else ignore disabled screens + } else if (screen) { + // Screen has been disabled -> remove + if (output.crtc == XCB_NONE && output.mode == XCB_NONE) { + qCDebug(lcQpaScreen) << "output" << screen->name() << "has been disabled"; + m_screens.removeOne(screen); + foreach (QXcbScreen *otherScreen, m_screens) + otherScreen->removeVirtualSibling((QPlatformScreen *) screen); + QXcbIntegration::instance()->destroyScreen(screen); + } else { + // Just update existing screen + screen->updateGeometry(output.config_timestamp); + const bool wasPrimary = screen->isPrimary(); + screen->setPrimary(checkOutputIsPrimary(output.window, output.output)); + if (screen->mode() != output.mode) + screen->updateRefreshRate(output.mode); + + // If the screen became primary, reshuffle the order in QGuiApplicationPrivate + // TODO: add a proper mechanism for updating primary screen + if (!wasPrimary && screen->isPrimary()) { + QScreen *realScreen = static_cast<QPlatformScreen*>(screen)->screen(); + QGuiApplicationPrivate::screen_list.removeOne(realScreen); + QGuiApplicationPrivate::screen_list.prepend(realScreen); + m_screens.removeOne(screen); + m_screens.prepend(screen); + } + qCDebug(lcQpaScreen) << "output has changed" << screen; + } + } + if (!m_screens.isEmpty()) + qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name(); + else + qCDebug(lcQpaScreen) << "no outputs"; + } +} + +void QXcbConnection::initializeScreens() { xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup); int xcbScreenNumber = 0; // screen number in the xcb sense - QList<QXcbScreen *> activeScreens; - QList<QXcbScreen *> newScreens; QXcbScreen* primaryScreen = NULL; while (it.rem) { // Each "screen" in xcb terminology is a virtual desktop, @@ -161,59 +307,73 @@ void QXcbConnection::updateScreens() xcb_generic_error_t *error = NULL; xcb_randr_get_output_primary_cookie_t primaryCookie = xcb_randr_get_output_primary(xcb_connection(), xcbScreen->root); + // TODO: RRGetScreenResources has to be called on each X display at least once before + // RRGetScreenResourcesCurrent can be used - we can't know if we are the first application + // to do so or not, so we always call the slower version here. Ideally we should share some + // global flag (an atom on root window maybe) that at least other Qt apps would understand + // and could call RRGetScreenResourcesCurrent here, speeding up start. xcb_randr_get_screen_resources_cookie_t resourcesCookie = xcb_randr_get_screen_resources(xcb_connection(), xcbScreen->root); - xcb_randr_get_output_primary_reply_t *primary = - xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error); + QScopedPointer<xcb_randr_get_output_primary_reply_t, QScopedPointerPodDeleter> primary( + xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error)); if (!primary || error) { - qWarning("QXcbConnection: Failed to get the primary output of the screen"); + qWarning("failed to get the primary output of the screen"); free(error); } else { - xcb_randr_get_screen_resources_reply_t *resources = - xcb_randr_get_screen_resources_reply(xcb_connection(), resourcesCookie, &error); + QScopedPointer<xcb_randr_get_screen_resources_reply_t, QScopedPointerPodDeleter> resources( + xcb_randr_get_screen_resources_reply(xcb_connection(), resourcesCookie, &error)); if (!resources || error) { - qWarning("QXcbConnection: Failed to get the screen resources"); + qWarning("failed to get the screen resources"); free(error); } else { xcb_timestamp_t timestamp = resources->config_timestamp; - outputCount = xcb_randr_get_screen_resources_outputs_length(resources); - xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_outputs(resources); + outputCount = xcb_randr_get_screen_resources_outputs_length(resources.data()); + xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_outputs(resources.data()); for (int i = 0; i < outputCount; i++) { - xcb_randr_get_output_info_reply_t *output = + QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> output( xcb_randr_get_output_info_reply(xcb_connection(), - xcb_randr_get_output_info_unchecked(xcb_connection(), outputs[i], timestamp), NULL); + xcb_randr_get_output_info_unchecked(xcb_connection(), outputs[i], timestamp), NULL)); + + // Invalid, disconnected or disabled output if (output == NULL) continue; + if (output->connection != XCB_RANDR_CONNECTION_CONNECTED) { + qCDebug(lcQpaScreen, "Output %s is not connected", qPrintable( + QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()), + xcb_randr_get_output_info_name_length(output.data())))); + continue; + } if (output->crtc == XCB_NONE) { - qCDebug(lcQpaScreen, "output %s is not connected", qPrintable( - QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output), - xcb_randr_get_output_info_name_length(output)))); + qCDebug(lcQpaScreen, "Output %s is not enabled", qPrintable( + QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()), + xcb_randr_get_output_info_name_length(output.data())))); continue; } - QXcbScreen *screen = findOrCreateScreen(newScreens, xcbScreenNumber, xcbScreen, output); + QXcbScreen *screen = createScreen(xcbScreenNumber, xcbScreen, outputs[i], output.data()); siblings << screen; - activeScreens << screen; ++connectedOutputCount; + m_screens << screen; + // There can be multiple outputs per screen, use either // the first or an exact match. An exact match isn't // always available if primary->output is XCB_NONE // or currently disconnected output. if (m_primaryScreenNumber == xcbScreenNumber) { if (!primaryScreen || (primary && outputs[i] == primary->output)) { + if (primaryScreen) + primaryScreen->setPrimary(false); primaryScreen = screen; + primaryScreen->setPrimary(true); siblings.prepend(siblings.takeLast()); } } - free(output); } } - free(resources); } - free(primary); } foreach (QPlatformScreen* s, siblings) ((QXcbScreen*)s)->setVirtualSiblings(siblings); @@ -221,47 +381,7 @@ void QXcbConnection::updateScreens() ++xcbScreenNumber; } // for each xcb screen - QXcbIntegration *integration = QXcbIntegration::instance(); - - // Rebuild screen list, ensuring primary screen is always in front, - // both in the QXcbConnection::m_screens list as well as in the - // QGuiApplicationPrivate::screen_list list, which gets updated via - // - screen added: integration->screenAdded() - // - screen removed: integration->destroyScreen - - // Gather screens to delete - QList<QXcbScreen*> screensToDelete; - for (int i = m_screens.count() - 1; i >= 0; --i) { - if (!activeScreens.contains(m_screens[i])) { - screensToDelete.append(m_screens.takeAt(i)); - } - } - - // If there is a new primary screen, add that one first - if (newScreens.contains(primaryScreen)) { - newScreens.removeOne(primaryScreen); - m_screens.prepend(primaryScreen); - qCDebug(lcQpaScreen) << "adding as primary" << primaryScreen; - integration->screenAdded(primaryScreen, true); - } - - // Add the remaining new screens - foreach (QXcbScreen* screen, newScreens) { - m_screens.append(screen); - qCDebug(lcQpaScreen) << "adding" << screen; - integration->screenAdded(screen); - } - - // Delete the old screens, now that the new ones were added - // and we are sure that there is at least one screen available - foreach (QXcbScreen* screen, screensToDelete) { - qCDebug(lcQpaScreen) << "removing" << screen; - integration->destroyScreen(screen); - } - - // Ensure that the primary screen is first in m_screens too - // (in case the assignment of primary was the only change, - // without adding or removing screens) + // Ensure the primary screen is first in the list if (primaryScreen) { Q_ASSERT(!m_screens.isEmpty()); if (m_screens.first() != primaryScreen) { @@ -270,13 +390,15 @@ void QXcbConnection::updateScreens() } } + // Push the screens to QApplication + QXcbIntegration *integration = QXcbIntegration::instance(); + foreach (QXcbScreen* screen, m_screens) { + qCDebug(lcQpaScreen) << "adding" << screen << "(Primary:" << screen->isPrimary() << ")"; + integration->screenAdded(screen, screen->isPrimary()); + } + if (!m_screens.isEmpty()) qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name(); - else - // QTBUG-40174, QTBUG-42985: If there are no outputs, then there must be - // no QScreen instances; a Qt application can survive this situation, and - // start rendering again later when there is a screen again. - qCDebug(lcQpaScreen) << "xcb connection has no outputs"; } QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName) @@ -343,7 +465,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra m_netWmUserTime = XCB_CURRENT_TIME; initializeXRandr(); - updateScreens(); + initializeScreens(); if (m_screens.isEmpty()) qFatal("QXcbConnection: no screens available"); @@ -943,14 +1065,14 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) m_clipboard->handleXFixesSelectionRequest((xcb_xfixes_selection_notify_event_t *)event); #endif handled = true; + } else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_NOTIFY) { + updateScreens((xcb_randr_notify_event_t *)event); + handled = true; } else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY) { - updateScreens(); xcb_randr_screen_change_notify_event_t *change_event = (xcb_randr_screen_change_notify_event_t *)event; foreach (QXcbScreen *s, m_screens) { - if (s->root() == change_event->root ) { + if (s->root() == change_event->root ) s->handleScreenChange(change_event); - s->updateRefreshRate(); - } } handled = true; #ifndef QT_NO_XKB @@ -1178,7 +1300,8 @@ xcb_timestamp_t QXcbConnection::getTimestamp() xcb_window_t QXcbConnection::rootWindow() { - return primaryScreen()->root(); + QXcbScreen *s = primaryScreen(); + return s ? s->root() : 0; } #ifdef XCB_USE_XLIB @@ -1653,6 +1776,17 @@ void QXcbConnection::initializeXRandr() has_randr_extension = false; } free(xrandr_query); + + xcb_screen_iterator_t rootIter = xcb_setup_roots_iterator(m_setup); + for (; rootIter.rem; xcb_screen_next(&rootIter)) { + xcb_randr_select_input(xcb_connection(), + rootIter.data->root, + XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE | + XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE | + XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE | + XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY + ); + } } void QXcbConnection::initializeXShape() diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 97c2590708..4c014bc6e2 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -35,6 +35,7 @@ #define QXCBCONNECTION_H #include <xcb/xcb.h> +#include <xcb/randr.h> #include "qxcbexport.h" #include <QHash> @@ -495,9 +496,15 @@ private: void initializeXShape(); void initializeXKB(); void handleClientMessageEvent(const xcb_client_message_event_t *event); - QXcbScreen* findOrCreateScreen(QList<QXcbScreen *>& newScreens, int screenNumber, - xcb_screen_t* xcbScreen, xcb_randr_get_output_info_reply_t *output = NULL); - void updateScreens(); + QXcbScreen* createScreen(int screenNumber, xcb_screen_t* xcbScreen, + xcb_randr_output_t outputId = XCB_NONE, + xcb_randr_get_output_info_reply_t *output = 0); + QXcbScreen* findScreenForCrtc(xcb_window_t rootWindow, xcb_randr_crtc_t crtc); + QXcbScreen* findScreenForOutput(xcb_window_t rootWindow, xcb_randr_output_t output); + xcb_screen_t* xcbScreenForRootWindow(xcb_window_t rootWindow, int *xcbScreenNumber = 0); + bool checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output); + void initializeScreens(); + void updateScreens(const xcb_randr_notify_event_t *event); void handleButtonPress(xcb_generic_event_t *event); void handleButtonRelease(xcb_generic_event_t *event); void handleMotionNotify(xcb_generic_event_t *event); diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index a375128288..75ffaa37bb 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -93,13 +93,21 @@ QXcbNativeInterface::QXcbNativeInterface() : void QXcbNativeInterface::beep() // For QApplication::beep() { - QPlatformScreen *screen = QGuiApplication::primaryScreen()->handle(); + QScreen *priScreen = QGuiApplication::primaryScreen(); + if (!priScreen) + return; + QPlatformScreen *screen = priScreen->handle(); + if (!screen) + return; xcb_connection_t *connection = static_cast<QXcbScreen *>(screen)->xcb_connection(); xcb_bell(connection, 0); } static inline QXcbSystemTrayTracker *systemTrayTracker(const QScreen *s) { + if (!s) + return Q_NULLPTR; + return static_cast<const QXcbScreen *>(s->handle())->connection()->systemTrayTracker(); } @@ -179,6 +187,9 @@ void *QXcbNativeInterface::nativeResourceForIntegration(const QByteArray &resour case AtspiBus: result = atspiBus(); break; + case Connection: + result = connection(); + break; default: break; } @@ -355,16 +366,25 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio void *QXcbNativeInterface::appTime(const QXcbScreen *screen) { + if (!screen) + return Q_NULLPTR; + return reinterpret_cast<void *>(quintptr(screen->connection()->time())); } void *QXcbNativeInterface::appUserTime(const QXcbScreen *screen) { + if (!screen) + return Q_NULLPTR; + return reinterpret_cast<void *>(quintptr(screen->connection()->netWmUserTime())); } void *QXcbNativeInterface::getTimestamp(const QXcbScreen *screen) { + if (!screen) + return Q_NULLPTR; + return reinterpret_cast<void *>(quintptr(screen->connection()->getTimestamp())); } @@ -400,10 +420,16 @@ void *QXcbNativeInterface::display() #ifdef XCB_USE_XLIB QXcbIntegration *integration = QXcbIntegration::instance(); QXcbConnection *defaultConnection = integration->defaultConnection(); - return defaultConnection->xlib_display(); -#else - return 0; + if (defaultConnection) + return defaultConnection->xlib_display(); #endif + return Q_NULLPTR; +} + +void *QXcbNativeInterface::connection() +{ + QXcbIntegration *integration = QXcbIntegration::instance(); + return integration->defaultConnection()->xcb_connection(); } void *QXcbNativeInterface::atspiBus() @@ -429,12 +455,16 @@ void *QXcbNativeInterface::atspiBus() void QXcbNativeInterface::setAppTime(QScreen* screen, xcb_timestamp_t time) { - static_cast<QXcbScreen *>(screen->handle())->connection()->setTime(time); + if (screen) { + static_cast<QXcbScreen *>(screen->handle())->connection()->setTime(time); + } } void QXcbNativeInterface::setAppUserTime(QScreen* screen, xcb_timestamp_t time) { - static_cast<QXcbScreen *>(screen->handle())->connection()->setNetWmUserTime(time); + if (screen) { + static_cast<QXcbScreen *>(screen->handle())->connection()->setNetWmUserTime(time); + } } void QXcbNativeInterface::setStartupId(const char *data) @@ -450,9 +480,11 @@ QXcbScreen *QXcbNativeInterface::qPlatformScreenForWindow(QWindow *window) { QXcbScreen *screen; if (window) { - screen = static_cast<QXcbScreen *>(window->screen()->handle()); + QScreen *qs = window->screen(); + screen = static_cast<QXcbScreen *>(qs ? qs->handle() : Q_NULLPTR); } else { - screen = static_cast<QXcbScreen *>(QGuiApplication::primaryScreen()->handle()); + QScreen *qs = QGuiApplication::primaryScreen(); + screen = static_cast<QXcbScreen *>(qs ? qs->handle() : Q_NULLPTR); } return screen; } @@ -461,23 +493,23 @@ void *QXcbNativeInterface::displayForWindow(QWindow *window) { #if defined(XCB_USE_XLIB) QXcbScreen *screen = qPlatformScreenForWindow(window); - return screen->connection()->xlib_display(); + return screen ? screen->connection()->xlib_display() : Q_NULLPTR; #else Q_UNUSED(window); - return 0; + return Q_NULLPTR; #endif } void *QXcbNativeInterface::connectionForWindow(QWindow *window) { QXcbScreen *screen = qPlatformScreenForWindow(window); - return screen->xcb_connection(); + return screen ? screen->xcb_connection() : Q_NULLPTR; } void *QXcbNativeInterface::screenForWindow(QWindow *window) { QXcbScreen *screen = qPlatformScreenForWindow(window); - return screen->screen(); + return screen ? screen->screen() : Q_NULLPTR; } void QXcbNativeInterface::addHandler(QXcbNativeInterfaceHandler *handler) diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h index 054c0ec2b5..f88b710864 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.h +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h @@ -100,6 +100,7 @@ public: void *rootWindow(); void *display(); void *atspiBus(); + void *connection(); static void setStartupId(const char *); static void setAppTime(QScreen *screen, xcb_timestamp_t time); static void setAppUserTime(QScreen *screen, xcb_timestamp_t time); diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 78ced43af8..383adf9734 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -48,10 +48,15 @@ QT_BEGIN_NAMESPACE QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, - xcb_randr_get_output_info_reply_t *output, const QString &outputName, int number) + xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output, + QString outputName, int number) : QXcbObject(connection) , m_screen(scr) + , m_output(outputId) , m_crtc(output ? output->crtc : 0) + , m_mode(XCB_NONE) + , m_primary(false) + , m_rotation(XCB_RANDR_ROTATION_ROTATE_0) , m_outputName(outputName) , m_outputSizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize()) , m_virtualSize(scr->width_in_pixels, scr->height_in_pixels) @@ -67,11 +72,20 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, , m_antialiasingEnabled(-1) , m_xSettings(0) { - if (connection->hasXRandr()) + if (connection->hasXRandr()) { xcb_randr_select_input(xcb_connection(), screen()->root, true); - - updateGeometry(output ? output->timestamp : 0); - updateRefreshRate(); + xcb_randr_get_crtc_info_cookie_t crtcCookie = + xcb_randr_get_crtc_info_unchecked(xcb_connection(), m_crtc, output ? output->timestamp : 0); + xcb_randr_get_crtc_info_reply_t *crtc = + xcb_randr_get_crtc_info_reply(xcb_connection(), crtcCookie, NULL); + if (crtc) { + updateGeometry(QRect(crtc->x, crtc->y, crtc->width, crtc->height), crtc->rotation); + updateRefreshRate(crtc->mode); + free(crtc); + } + } else { + updateGeometry(output ? output->timestamp : 0); + } const int dpr = int(devicePixelRatio()); // On VNC, it can be that physical size is unknown while @@ -352,9 +366,15 @@ QPlatformCursor *QXcbScreen::cursor() const */ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event) { - updateGeometry(change_event->config_timestamp); + // No need to do anything when screen rotation did not change - if any + // xcb output geometry has changed, we will get RRCrtcChangeNotify and + // RROutputChangeNotify events next + if (change_event->rotation == m_rotation) + return; - switch (change_event->rotation) { + m_rotation = change_event->rotation; + updateGeometry(change_event->timestamp); + switch (m_rotation) { case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal m_orientation = Qt::LandscapeOrientation; m_virtualSize.setWidth(change_event->width); @@ -406,35 +426,37 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp) { - QRect xGeometry; - QRect xAvailableGeometry; + xcb_randr_get_crtc_info_cookie_t crtcCookie = + xcb_randr_get_crtc_info_unchecked(xcb_connection(), m_crtc, timestamp); + xcb_randr_get_crtc_info_reply_t *crtc = + xcb_randr_get_crtc_info_reply(xcb_connection(), crtcCookie, NULL); + if (crtc) { + updateGeometry(QRect(crtc->x, crtc->y, crtc->width, crtc->height), crtc->rotation); + free(crtc); + } +} - if (connection()->hasXRandr()) { - xcb_randr_get_crtc_info_reply_t *crtc = xcb_randr_get_crtc_info_reply(xcb_connection(), - xcb_randr_get_crtc_info_unchecked(xcb_connection(), m_crtc, timestamp), NULL); - if (crtc) { - xGeometry = QRect(crtc->x, crtc->y, crtc->width, crtc->height); - xAvailableGeometry = xGeometry; - switch (crtc->rotation) { - case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal - m_orientation = Qt::LandscapeOrientation; - m_sizeMillimeters = m_outputSizeMillimeters; - break; - case XCB_RANDR_ROTATION_ROTATE_90: // xrandr --rotate left - m_orientation = Qt::PortraitOrientation; - m_sizeMillimeters = m_outputSizeMillimeters.transposed(); - break; - case XCB_RANDR_ROTATION_ROTATE_180: // xrandr --rotate inverted - m_orientation = Qt::InvertedLandscapeOrientation; - m_sizeMillimeters = m_outputSizeMillimeters; - break; - case XCB_RANDR_ROTATION_ROTATE_270: // xrandr --rotate right - m_orientation = Qt::InvertedPortraitOrientation; - m_sizeMillimeters = m_outputSizeMillimeters.transposed(); - break; - } - free(crtc); - } +void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation) +{ + QRect xGeometry = geom; + QRect xAvailableGeometry = xGeometry; + switch (rotation) { + case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal + m_orientation = Qt::LandscapeOrientation; + m_sizeMillimeters = m_outputSizeMillimeters; + break; + case XCB_RANDR_ROTATION_ROTATE_90: // xrandr --rotate left + m_orientation = Qt::PortraitOrientation; + m_sizeMillimeters = m_outputSizeMillimeters.transposed(); + break; + case XCB_RANDR_ROTATION_ROTATE_180: // xrandr --rotate inverted + m_orientation = Qt::InvertedLandscapeOrientation; + m_sizeMillimeters = m_outputSizeMillimeters; + break; + case XCB_RANDR_ROTATION_ROTATE_270: // xrandr --rotate right + m_orientation = Qt::InvertedPortraitOrientation; + m_sizeMillimeters = m_outputSizeMillimeters.transposed(); + break; } xcb_get_property_reply_t * workArea = @@ -463,31 +485,38 @@ void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp) m_geometry = QRect(xGeometry.topLeft()/dpr, xGeometry.size()/dpr); m_nativeGeometry = QRect(xGeometry.topLeft(), xGeometry.size()); m_availableGeometry = QRect(xAvailableGeometry.topLeft()/dpr, xAvailableGeometry.size()/dpr); - QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry); } -void QXcbScreen::updateRefreshRate() +void QXcbScreen::updateRefreshRate(xcb_randr_mode_t mode) { if (!connection()->hasXRandr()) return; - int rate = m_refreshRate; - - xcb_randr_get_screen_info_reply_t *screenInfoReply = - xcb_randr_get_screen_info_reply(xcb_connection(), xcb_randr_get_screen_info_unchecked(xcb_connection(), m_screen->root), 0); - - if (screenInfoReply) { - rate = screenInfoReply->rate; - free(screenInfoReply); - } - - if (rate == m_refreshRate) + if (m_mode == mode) return; - m_refreshRate = rate; + // we can safely use get_screen_resources_current here, because in order to + // get here, we must have called get_screen_resources before + xcb_randr_get_screen_resources_current_cookie_t resourcesCookie = + xcb_randr_get_screen_resources_current_unchecked(xcb_connection(), m_screen->root); + xcb_randr_get_screen_resources_current_reply_t *resources = + xcb_randr_get_screen_resources_current_reply(xcb_connection(), resourcesCookie, NULL); + if (resources) { + xcb_randr_mode_info_iterator_t modesIter = + xcb_randr_get_screen_resources_current_modes_iterator(resources); + for (; modesIter.rem; xcb_randr_mode_info_next(&modesIter)) { + xcb_randr_mode_info_t *modeInfo = modesIter.data; + if (modeInfo->id == mode) { + m_refreshRate = modeInfo->dot_clock / (modeInfo->htotal * modeInfo->vtotal); + m_mode = mode; + break; + } + } - QWindowSystemInterface::handleScreenRefreshRateChange(QPlatformScreen::screen(), rate); + free(resources); + QWindowSystemInterface::handleScreenRefreshRateChange(QPlatformScreen::screen(), m_refreshRate); + } } QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height) const @@ -703,7 +732,7 @@ Q_XCB_EXPORT QDebug operator<<(QDebug debug, const QXcbScreen *screen) { const QDebugStateSaver saver(debug); debug.nospace(); - debug << "QXcbScreen(" << (void *)screen; + debug << "QXcbScreen(" << (const void *)screen; if (screen) { debug << fixed << qSetRealNumberPrecision(1); debug << ", name=" << screen->name(); diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index 53ad413541..3f228465f2 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -58,7 +58,8 @@ class Q_XCB_EXPORT QXcbScreen : public QXcbObject, public QPlatformScreen { public: QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, - xcb_randr_get_output_info_reply_t *output, const QString &outputName, int number); + xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output, + QString outputName, int number); ~QXcbScreen(); QPixmap grabWindow(WId window, int x, int y, int width, int height) const Q_DECL_OVERRIDE; @@ -80,11 +81,19 @@ public: Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE { return m_orientation; } QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE { return m_siblings; } void setVirtualSiblings(QList<QPlatformScreen *> sl) { m_siblings = sl; } + void removeVirtualSibling(QPlatformScreen *s) { m_siblings.removeOne(s); } + void addVirtualSibling(QPlatformScreen *s) { ((QXcbScreen *) s)->isPrimary() ? m_siblings.prepend(s) : m_siblings.append(s); } + + void setPrimary(bool primary) { m_primary = primary; } + bool isPrimary() const { return m_primary; } int screenNumber() const { return m_number; } xcb_screen_t *screen() const { return m_screen; } xcb_window_t root() const { return m_screen->root; } + xcb_randr_output_t output() const { return m_output; } + xcb_randr_crtc_t crtc() const { return m_crtc; } + xcb_randr_mode_t mode() const { return m_mode; } xcb_window_t clientLeader() const { return m_clientLeader; } @@ -98,8 +107,9 @@ public: QString name() const Q_DECL_OVERRIDE { return m_outputName; } void handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event); - void updateGeometry(xcb_timestamp_t timestamp); - void updateRefreshRate(); + void updateGeometry(const QRect &geom, uint8_t rotation); + void updateGeometry(xcb_timestamp_t timestamp = XCB_TIME_CURRENT_TIME); + void updateRefreshRate(xcb_randr_mode_t mode); void readXResources(); @@ -117,7 +127,12 @@ private: void sendStartupMessage(const QByteArray &message) const; xcb_screen_t *m_screen; + xcb_randr_output_t m_output; xcb_randr_crtc_t m_crtc; + xcb_randr_mode_t m_mode; + bool m_primary; + uint8_t m_rotation; + QString m_outputName; QSizeF m_outputSizeMillimeters; QSizeF m_sizeMillimeters; diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp index 33e67a14b1..328b72234a 100644 --- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp +++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp @@ -125,7 +125,7 @@ static void sm_setProperty(const QString &name, const QString &value) QByteArray v = value.toUtf8(); SmPropValue prop; prop.length = v.length(); - prop.value = (SmPointer) v.constData(); + prop.value = (SmPointer) const_cast<char *>(v.constData()); sm_setProperty(name.toLatin1().data(), SmARRAY8, 1, &prop); } diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 6d2f5276b3..0dde679a7a 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1372,6 +1372,8 @@ void QXcbWindow::setParent(const QPlatformWindow *parent) xcb_parent_id = qXcbParent->xcb_window(); m_embedded = qXcbParent->window()->type() == Qt::ForeignWindow; } else { + if (!xcbScreen()) + return; xcb_parent_id = xcbScreen()->root(); m_embedded = false; } diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp index 9fde8aeedc..7748a8af01 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp +++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp @@ -353,10 +353,10 @@ void QPageSetupWidget::initPageSizes() // If PdfFormat or no available printer page sizes, populate with all page sizes for (int id = 0; id < QPageSize::LastPageSize; ++id) { if (QPageSize::PageSizeId(id) == QPageSize::Custom) { - m_ui.pageSizeCombo->addItem(tr("Custom"), id); + m_ui.pageSizeCombo->addItem(tr("Custom"), QVariant::fromValue(QPageSize::Custom)); } else { QPageSize pageSize = QPageSize(QPageSize::PageSizeId(id)); - m_ui.pageSizeCombo->addItem(pageSize.name(), id); + m_ui.pageSizeCombo->addItem(pageSize.name(), QVariant::fromValue(pageSize.id())); } } diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp index 65af6fadf7..5b3184a20d 100644 --- a/src/printsupport/kernel/qprintengine_win.cpp +++ b/src/printsupport/kernel/qprintengine_win.cpp @@ -89,6 +89,17 @@ QWin32PrintEngine::QWin32PrintEngine(QPrinter::PrinterMode mode) d->initialize(); } +static QByteArray msgBeginFailed(const char *function, const DOCINFO &d) +{ + QString result; + QTextStream str(&result); + str << "QWin32PrintEngine::begin: " << function << " failed, document \"" + << QString::fromWCharArray(d.lpszDocName) << '"'; + if (d.lpszOutput[0]) + str << ", file \"" << QString::fromWCharArray(d.lpszOutput) << '"'; + return result.toLocal8Bit(); +} + bool QWin32PrintEngine::begin(QPaintDevice *pdev) { Q_D(QWin32PrintEngine); @@ -123,12 +134,12 @@ bool QWin32PrintEngine::begin(QPaintDevice *pdev) if (d->printToFile) di.lpszOutput = d->fileName.isEmpty() ? L"FILE:" : reinterpret_cast<const wchar_t *>(d->fileName.utf16()); if (ok && StartDoc(d->hdc, &di) == SP_ERROR) { - qErrnoWarning("QWin32PrintEngine::begin: StartDoc failed"); + qErrnoWarning(msgBeginFailed("StartDoc", di)); ok = false; } if (StartPage(d->hdc) <= 0) { - qErrnoWarning("QWin32PrintEngine::begin: StartPage failed"); + qErrnoWarning(msgBeginFailed("StartPage", di)); ok = false; } @@ -175,8 +186,10 @@ bool QWin32PrintEngine::end() return true; if (d->hdc) { - EndPage(d->hdc); // end; printing done - EndDoc(d->hdc); + if (EndPage(d->hdc) <= 0) // end; printing done + qErrnoWarning("QWin32PrintEngine::end: EndPage failed (%p)", d->hdc); + if (EndDoc(d->hdc) <= 0) + qErrnoWarning("QWin32PrintEngine::end: EndDoc failed"); } d->state = QPrinter::Idle; @@ -201,10 +214,8 @@ bool QWin32PrintEngine::newPage() } if (d->reinit) { - if (!d->resetDC()) { - qErrnoWarning("QWin32PrintEngine::newPage: ResetDC failed"); + if (!d->resetDC()) return false; - } d->reinit = false; } @@ -241,6 +252,8 @@ bool QWin32PrintEngine::newPage() d->reinit = false; } success = (StartPage(d->hdc) > 0); + if (!success) + qErrnoWarning("Win32PrintEngine::newPage: StartPage failed (2)"); } if (!success) { d->state = QPrinter::Aborted; @@ -966,6 +979,21 @@ void QWin32PrintEnginePrivate::doReinit() } } +bool QWin32PrintEnginePrivate::resetDC() +{ + if (!hdc) { + qWarning() << "ResetDC() called with null hdc."; + return false; + } + const HDC oldHdc = hdc; + const HDC hdc = ResetDC(oldHdc, devMode); + if (!hdc) { + const int lastError = GetLastError(); + qErrnoWarning(lastError, "ResetDC() on %p failed (%d)", oldHdc, lastError); + } + return hdc != 0; +} + static int indexOfId(const QList<QPrint::InputSlot> &inputSlots, QPrint::InputSlotId id) { for (int i = 0; i < inputSlots.size(); ++i) { diff --git a/src/printsupport/kernel/qprintengine_win_p.h b/src/printsupport/kernel/qprintengine_win_p.h index 2f2a92f822..98a4cff1a8 100644 --- a/src/printsupport/kernel/qprintengine_win_p.h +++ b/src/printsupport/kernel/qprintengine_win_p.h @@ -152,10 +152,7 @@ public: is handled in the next begin or newpage. */ void doReinit(); - inline bool resetDC() { - hdc = ResetDC(hdc, devMode); - return hdc != 0; - } + bool resetDC(); void strokePath(const QPainterPath &path, const QColor &color); void fillPath(const QPainterPath &path, const QColor &color); diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index e12764636a..8db06e6831 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -506,7 +506,7 @@ static QVariant qGetBinaryData(SQLHANDLE hStmt, int column) r = SQLGetData(hStmt, column+1, SQL_C_BINARY, - (SQLPOINTER)(fieldVal.constData() + read), + const_cast<char *>(fieldVal.constData() + read), colSize, &lengthIndicator); if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) @@ -1361,7 +1361,7 @@ bool QODBCResult::exec() case QVariant::Date: { QByteArray &ba = tmpStorage[i]; ba.resize(sizeof(DATE_STRUCT)); - DATE_STRUCT *dt = (DATE_STRUCT *)ba.constData(); + DATE_STRUCT *dt = (DATE_STRUCT *)const_cast<char *>(ba.constData()); QDate qdt = val.toDate(); dt->year = qdt.year(); dt->month = qdt.month(); @@ -1380,7 +1380,7 @@ bool QODBCResult::exec() case QVariant::Time: { QByteArray &ba = tmpStorage[i]; ba.resize(sizeof(TIME_STRUCT)); - TIME_STRUCT *dt = (TIME_STRUCT *)ba.constData(); + TIME_STRUCT *dt = (TIME_STRUCT *)const_cast<char *>(ba.constData()); QTime qdt = val.toTime(); dt->hour = qdt.hour(); dt->minute = qdt.minute(); @@ -1399,7 +1399,7 @@ bool QODBCResult::exec() case QVariant::DateTime: { QByteArray &ba = tmpStorage[i]; ba.resize(sizeof(TIMESTAMP_STRUCT)); - TIMESTAMP_STRUCT * dt = (TIMESTAMP_STRUCT *)ba.constData(); + TIMESTAMP_STRUCT * dt = (TIMESTAMP_STRUCT *)const_cast<char *>(ba.constData()); QDateTime qdt = val.toDateTime(); dt->year = qdt.date().year(); dt->month = qdt.date().month(); @@ -1438,7 +1438,7 @@ bool QODBCResult::exec() SQL_INTEGER, 0, 0, - (void *) val.constData(), + const_cast<void *>(val.constData()), 0, *ind == SQL_NULL_DATA ? ind : NULL); break; @@ -1450,7 +1450,7 @@ bool QODBCResult::exec() SQL_NUMERIC, 15, 0, - (void *) val.constData(), + const_cast<void *>(val.constData()), 0, *ind == SQL_NULL_DATA ? ind : NULL); break; @@ -1462,7 +1462,7 @@ bool QODBCResult::exec() SQL_DOUBLE, 0, 0, - (void *) val.constData(), + const_cast<void *>(val.constData()), 0, *ind == SQL_NULL_DATA ? ind : NULL); break; @@ -1474,7 +1474,7 @@ bool QODBCResult::exec() SQL_BIGINT, 0, 0, - (void *) val.constData(), + const_cast<void *>(val.constData()), 0, *ind == SQL_NULL_DATA ? ind : NULL); break; @@ -1486,7 +1486,7 @@ bool QODBCResult::exec() SQL_BIGINT, 0, 0, - (void *) val.constData(), + const_cast<void *>(val.constData()), 0, *ind == SQL_NULL_DATA ? ind : NULL); break; @@ -1501,7 +1501,7 @@ bool QODBCResult::exec() SQL_LONGVARBINARY, val.toByteArray().size(), 0, - (void *) val.toByteArray().constData(), + const_cast<char *>(val.toByteArray().constData()), val.toByteArray().size(), ind); break; @@ -1513,7 +1513,7 @@ bool QODBCResult::exec() SQL_BIT, 0, 0, - (void *) val.constData(), + const_cast<void *>(val.constData()), 0, *ind == SQL_NULL_DATA ? ind : NULL); break; @@ -1535,7 +1535,7 @@ bool QODBCResult::exec() strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR, 0, // god knows... don't change this! 0, - (void *)ba.data(), + ba.data(), ba.size(), ind); break; @@ -1548,7 +1548,7 @@ bool QODBCResult::exec() strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR, strSize, 0, - (SQLPOINTER)ba.constData(), + const_cast<char *>(ba.constData()), ba.size(), ind); break; @@ -1568,7 +1568,7 @@ bool QODBCResult::exec() strSize > 254 ? SQL_LONGVARCHAR : SQL_VARCHAR, strSize, 0, - (void *)str.constData(), + const_cast<char *>(str.constData()), strSize, ind); break; @@ -1585,7 +1585,7 @@ bool QODBCResult::exec() SQL_VARBINARY, ba.length() + 1, 0, - (void *) ba.constData(), + const_cast<char *>(ba.constData()), ba.length() + 1, ind); break; } @@ -1631,16 +1631,16 @@ bool QODBCResult::exec() for (i = 0; i < values.count(); ++i) { switch (values.at(i).type()) { case QVariant::Date: { - DATE_STRUCT ds = *((DATE_STRUCT *)tmpStorage.at(i).constData()); + DATE_STRUCT ds = *((DATE_STRUCT *)const_cast<char *>(tmpStorage.at(i).constData())); values[i] = QVariant(QDate(ds.year, ds.month, ds.day)); break; } case QVariant::Time: { - TIME_STRUCT dt = *((TIME_STRUCT *)tmpStorage.at(i).constData()); + TIME_STRUCT dt = *((TIME_STRUCT *)const_cast<char *>(tmpStorage.at(i).constData())); values[i] = QVariant(QTime(dt.hour, dt.minute, dt.second)); break; } case QVariant::DateTime: { TIMESTAMP_STRUCT dt = *((TIMESTAMP_STRUCT*) - tmpStorage.at(i).constData()); + const_cast<char *>(tmpStorage.at(i).constData())); values[i] = QVariant(QDateTime(QDate(dt.year, dt.month, dt.day), QTime(dt.hour, dt.minute, dt.second, dt.fraction / 1000000))); break; } @@ -1658,7 +1658,7 @@ bool QODBCResult::exec() if (bindValueType(i) & QSql::Out) { const QByteArray &first = tmpStorage.at(i); QVarLengthArray<SQLTCHAR> array; - array.append((SQLTCHAR *)first.constData(), first.size()); + array.append((const SQLTCHAR *)first.constData(), first.size()); values[i] = fromSQLTCHAR(array, first.size()/sizeof(SQLTCHAR)); } break; diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index 3aa2455ff0..5c67652cdb 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -448,7 +448,7 @@ QVariant QPSQLResult::data(int i) } case QVariant::ByteArray: { size_t len; - unsigned char *data = PQunescapeBytea((unsigned char*)val, &len); + unsigned char *data = PQunescapeBytea((const unsigned char*)val, &len); QByteArray ba((const char*)data, len); qPQfreemem(data); return QVariant(ba); @@ -1312,9 +1312,9 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const QByteArray ba(field.value().toByteArray()); size_t len; #if defined PG_VERSION_NUM && PG_VERSION_NUM-0 >= 80200 - unsigned char *data = PQescapeByteaConn(d->connection, (unsigned char*)ba.constData(), ba.size(), &len); + unsigned char *data = PQescapeByteaConn(d->connection, (const unsigned char*)ba.constData(), ba.size(), &len); #else - unsigned char *data = PQescapeBytea((unsigned char*)ba.constData(), ba.size(), &len); + unsigned char *data = PQescapeBytea((const unsigned char*)ba.constData(), ba.size(), &len); #endif r += QLatin1Char('\''); r += QLatin1String((const char*)data); diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index fa2080fe69..222bdd3f39 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -88,6 +88,7 @@ QT_BEGIN_NAMESPACE using QtMiscUtils::toHexUpper; +using QtMiscUtils::fromHex; /*! \namespace QTest @@ -2056,6 +2057,7 @@ static bool qInvokeTestMethod(const char *slotName, const char *data=0) /* For each entry in the data table, do: */ do { QTestResult::setSkipCurrentTest(false); + QTestResult::setBlacklistCurrentTest(false); if (!data || !qstrcmp(data, table.testData(curDataIndex)->dataTag())) { foundFunction = true; @@ -2087,6 +2089,7 @@ static bool qInvokeTestMethod(const char *slotName, const char *data=0) QTestResult::finishedCurrentTestFunction(); QTestResult::setSkipCurrentTest(false); + QTestResult::setBlacklistCurrentTest(false); QTestResult::setCurrentTestData(0); delete[] slot; @@ -2184,7 +2187,7 @@ char *toHexRepresentation(const char *ba, int length) /*! \internal Returns the same QByteArray but with only the ASCII characters still shown; - everything else is replaced with \c {\OOO}. + everything else is replaced with \c {\xHH}. */ char *toPrettyCString(const char *p, int length) { @@ -2193,14 +2196,30 @@ char *toPrettyCString(const char *p, int length) const char *end = p + length; char *dst = buffer.data(); + bool lastWasHexEscape = false; *dst++ = '"'; for ( ; p != end; ++p) { + // we can add: + // 1 byte: a single character + // 2 bytes: a simple escape sequence (\n) + // 3 bytes: "" and a character + // 4 bytes: an hex escape sequence (\xHH) if (dst - buffer.data() > 246) { - // plus the the quote, the three dots and NUL, it's 251, 252 or 255 + // plus the the quote, the three dots and NUL, it's 255 in the worst case trimmed = true; break; } + // check if we need to insert "" to break an hex escape sequence + if (Q_UNLIKELY(lastWasHexEscape)) { + if (fromHex(*p) != -1) { + // yes, insert it + *dst++ = '"'; + *dst++ = '"'; + } + lastWasHexEscape = false; + } + if (*p < 0x7f && *p >= 0x20 && *p != '\\' && *p != '"') { *dst++ = *p; continue; @@ -2230,10 +2249,12 @@ char *toPrettyCString(const char *p, int length) *dst++ = 't'; break; default: - // write as octal - *dst++ = '0' + ((uchar(*p) >> 6) & 7); - *dst++ = '0' + ((uchar(*p) >> 3) & 7); - *dst++ = '0' + ((uchar(*p)) & 7); + // print as hex escape + *dst++ = 'x'; + *dst++ = toHexUpper(uchar(*p) >> 4); + *dst++ = toHexUpper(uchar(*p)); + lastWasHexEscape = true; + break; } } @@ -2362,6 +2383,7 @@ static void qInvokeTestMethods(QObject *testObject) } QTestResult::setSkipCurrentTest(false); + QTestResult::setBlacklistCurrentTest(false); QTestResult::setCurrentTestFunction("cleanupTestCase"); invokeMethod(testObject, "cleanupTestCase()"); QTestResult::finishedCurrentTestData(); diff --git a/src/tools/qdoc/codechunk.h b/src/tools/qdoc/codechunk.h index ed898bcdc7..259012df90 100644 --- a/src/tools/qdoc/codechunk.h +++ b/src/tools/qdoc/codechunk.h @@ -76,6 +76,7 @@ public: void appendHotspot(); bool isEmpty() const { return s.isEmpty(); } + void clear() { s.clear(); } QString toString() const; QStringList toPath() const; QString left() const { return s.left(hotspot == -1 ? s.length() : hotspot); } diff --git a/src/tools/qdoc/config.cpp b/src/tools/qdoc/config.cpp index e3b2f0325d..13add73322 100644 --- a/src/tools/qdoc/config.cpp +++ b/src/tools/qdoc/config.cpp @@ -396,7 +396,7 @@ QString Config::getString(const QString& var) const while (i >= 0) { const ConfigVar& cv = configVars[i]; if (!cv.location_.isEmpty()) - (Location&) lastLocation_ = cv.location_; + const_cast<Config *>(this)->lastLocation_ = cv.location_; if (!cv.values_.isEmpty()) { if (!cv.plus_) value.clear(); @@ -443,7 +443,7 @@ QStringList Config::getStringList(const QString& var) const int i = configVars.size() - 1; while (i >= 0) { if (!configVars[i].location_.isEmpty()) - (Location&) lastLocation_ = configVars[i].location_; + const_cast<Config *>(this)->lastLocation_ = configVars[i].location_; if (configVars[i].plus_) values.append(configVars[i].values_); else @@ -478,7 +478,7 @@ QStringList Config::getCanonicalPathList(const QString& var, bool validate) cons while (i >= 0) { const ConfigVar& cv = configVars[i]; if (!cv.location_.isEmpty()) - (Location&) lastLocation_ = cv.location_; + const_cast<Config *>(this)->lastLocation_ = cv.location_; if (!cv.plus_) t.clear(); const QString d = cv.currentPath_; diff --git a/src/tools/qdoc/doc.cpp b/src/tools/qdoc/doc.cpp index 7965ea898f..e911eed28b 100644 --- a/src/tools/qdoc/doc.cpp +++ b/src/tools/qdoc/doc.cpp @@ -49,6 +49,7 @@ #include <ctype.h> #include <limits.h> #include <qdebug.h> +#include "generator.h" QT_BEGIN_NAMESPACE @@ -3319,9 +3320,7 @@ CodeMarker *Doc::quoteFromFile(const Location &location, QString dirPath = QFileInfo(filePath).path(); CodeMarker *marker = CodeMarker::markerForFileName(fileName); - quoter.quoteFromFile(userFriendlyFilePath, - code, - marker->markedUpCode(code, 0, location)); + quoter.quoteFromFile(userFriendlyFilePath, code, marker->markedUpCode(code, 0, location)); return marker; } diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index 7518b20fa3..00a292b17f 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -788,63 +788,63 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark NodeMultiMap::const_iterator n = nsmap.constBegin(); while (n != nsmap.constEnd()) { - const Node* node = n.value(); + Node* node = n.value(); switch (node->type()) { case Node::QmlType: - sections[QmlClass].appendMember((Node*)node); + sections[QmlClass].appendMember(node); break; case Node::Namespace: - sections[Namespace].appendMember((Node*)node); + sections[Namespace].appendMember(node); break; case Node::Class: - sections[Class].appendMember((Node*)node); + sections[Class].appendMember(node); break; case Node::Enum: - sections[Enum].appendMember((Node*)node); + sections[Enum].appendMember(node); break; case Node::Typedef: - sections[Typedef].appendMember((Node*)node); + sections[Typedef].appendMember(node); break; case Node::Function: { const FunctionNode* fn = static_cast<const FunctionNode*>(node); if (fn->isMacro()) - sections[Macro].appendMember((Node*)node); + sections[Macro].appendMember(node); else { Node* p = fn->parent(); if (p) { if (p->type() == Node::Class) - sections[MemberFunction].appendMember((Node*)node); + sections[MemberFunction].appendMember(node); else if (p->type() == Node::Namespace) { if (p->name().isEmpty()) - sections[GlobalFunction].appendMember((Node*)node); + sections[GlobalFunction].appendMember(node); else - sections[NamespaceFunction].appendMember((Node*)node); + sections[NamespaceFunction].appendMember(node); } else - sections[GlobalFunction].appendMember((Node*)node); + sections[GlobalFunction].appendMember(node); } else - sections[GlobalFunction].appendMember((Node*)node); + sections[GlobalFunction].appendMember(node); } break; } case Node::Property: - sections[Property].appendMember((Node*)node); + sections[Property].appendMember(node); break; case Node::Variable: - sections[Variable].appendMember((Node*)node); + sections[Variable].appendMember(node); break; case Node::QmlProperty: - sections[QmlProperty].appendMember((Node*)node); + sections[QmlProperty].appendMember(node); break; case Node::QmlSignal: - sections[QmlSignal].appendMember((Node*)node); + sections[QmlSignal].appendMember(node); break; case Node::QmlSignalHandler: - sections[QmlSignalHandler].appendMember((Node*)node); + sections[QmlSignalHandler].appendMember(node); break; case Node::QmlMethod: - sections[QmlMethod].appendMember((Node*)node); + sections[QmlMethod].appendMember(node); break; default: break; @@ -3349,6 +3349,7 @@ void HtmlGenerator::generateSectionInheritedList(const Section& section, const N } } +// generateSynopsis(qmn,relative,marker,CodeMarker::Detailed,false); void HtmlGenerator::generateSynopsis(const Node *node, const Node *relative, CodeMarker *marker, diff --git a/src/tools/qdoc/jscodemarker.cpp b/src/tools/qdoc/jscodemarker.cpp index 2a98b7372d..2538b46433 100644 --- a/src/tools/qdoc/jscodemarker.cpp +++ b/src/tools/qdoc/jscodemarker.cpp @@ -46,6 +46,7 @@ #include "qmlmarkupvisitor.h" #include "text.h" #include "tree.h" +#include "generator.h" QT_BEGIN_NAMESPACE @@ -128,12 +129,12 @@ QString JsCodeMarker::addMarkUp(const QString &code, QQmlJS::AST::Node::accept(ast, &visitor); output = visitor.markedUpCode(); } else { - location.warning(tr("Unable to parse JavaScript: \"%1\" at line %2, column %3").arg( + location.warning(location.fileName() + + tr("Unable to parse JavaScript: \"%1\" at line %2, column %3").arg( parser.errorMessage()).arg(parser.errorLineNumber()).arg( parser.errorColumnNumber())); output = protect(code); } - return output; } diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp index 25792a7c35..a6999d3856 100644 --- a/src/tools/qdoc/node.cpp +++ b/src/tools/qdoc/node.cpp @@ -807,7 +807,7 @@ FunctionNode *InnerNode::findFunctionNode(const QString& name) const that the function has the same name and signature as the \a clone node. */ -FunctionNode *InnerNode::findFunctionNode(const FunctionNode *clone) +FunctionNode *InnerNode::findFunctionNode(const FunctionNode *clone) const { QMap<QString,Node*>::ConstIterator c = primaryFunctionMap.constFind(clone->name()); if (c != primaryFunctionMap.constEnd()) { @@ -857,7 +857,7 @@ QStringList InnerNode::secondaryKeys() /*! */ -void InnerNode::setOverload(const FunctionNode *func, bool overlode) +void InnerNode::setOverload(FunctionNode *func, bool overlode) { Node *node = (Node *) func; Node *&primary = primaryFunctionMap[func->name()]; @@ -1017,7 +1017,7 @@ const EnumNode *InnerNode::findEnumNodeForValue(const QString &enumValue) const */ int InnerNode::overloadNumber(const FunctionNode *func) const { - Node *node = (Node *) func; + Node *node = const_cast<FunctionNode *>(func); if (primaryFunctionMap[func->name()] == node) { return 1; } @@ -1863,6 +1863,7 @@ void FunctionNode::setReimp(bool r) } /*! + Append \a parameter to the parameter list. */ void FunctionNode::addParameter(const Parameter& parameter) { diff --git a/src/tools/qdoc/node.h b/src/tools/qdoc/node.h index 73b705dd0f..654004e425 100644 --- a/src/tools/qdoc/node.h +++ b/src/tools/qdoc/node.h @@ -376,10 +376,10 @@ public: Node* findChildNode(const QString& name, Type type); virtual void findChildren(const QString& name, NodeList& nodes) const Q_DECL_OVERRIDE; FunctionNode* findFunctionNode(const QString& name) const; - FunctionNode* findFunctionNode(const FunctionNode* clone); + FunctionNode* findFunctionNode(const FunctionNode* clone) const; void addInclude(const QString &include); void setIncludes(const QStringList &includes); - void setOverload(const FunctionNode* func, bool overlode); + void setOverload(FunctionNode* func, bool overlode); void normalizeOverloads(); void makeUndocumentedChildrenInternal(); void deleteChildren(); @@ -904,6 +904,7 @@ public: } int overloadNumber() const; const QList<Parameter>& parameters() const { return params; } + void clearParams() { params.clear(); } QStringList parameterNames() const; QString rawParameters(bool names = false, bool values = false) const; const FunctionNode* reimplementedFrom() const { return rf; } diff --git a/src/tools/qdoc/qmlcodemarker.cpp b/src/tools/qdoc/qmlcodemarker.cpp index f8071c154e..86fc79be66 100644 --- a/src/tools/qdoc/qmlcodemarker.cpp +++ b/src/tools/qdoc/qmlcodemarker.cpp @@ -47,6 +47,7 @@ #include "qmlmarkupvisitor.h" #include "text.h" #include "tree.h" +#include "generator.h" QT_BEGIN_NAMESPACE @@ -205,8 +206,8 @@ static void replaceWithSpace(QString &str, int idx, int n) src/declarative/qml/qqmlscriptparser.cpp then modified to return a list of removed pragmas. - Searches for ".pragma <value>" declarations within \a script. - Currently supported pragmas are: library + Searches for ".pragma <value>" or ".import <stuff>" declarations + in \a script. Currently supported pragmas are: library */ QList<QQmlJS::AST::SourceLocation> QmlCodeMarker::extractPragmas(QString &script) { @@ -229,13 +230,22 @@ QList<QQmlJS::AST::SourceLocation> QmlCodeMarker::extractPragmas(QString &script token = l.lex(); - if (token != QQmlJSGrammar::T_IDENTIFIER || - l.tokenStartLine() != startLine || - script.mid(l.tokenOffset(), l.tokenLength()) != pragma) + if (token != QQmlJSGrammar::T_PRAGMA && token != QQmlJSGrammar::T_IMPORT) return removed; - + int endOffset = 0; + while (startLine == l.tokenStartLine()) { + endOffset = l.tokenLength() + l.tokenOffset(); + token = l.lex(); + } + replaceWithSpace(script, startOffset, endOffset - startOffset); + removed.append(QQmlJS::AST::SourceLocation(startOffset, + endOffset - startOffset, + startLine, + startColumn)); +#if 0 token = l.lex(); - + if (Generator::debugging()) + qDebug() << " third token"; if (token != QQmlJSGrammar::T_IDENTIFIER || l.tokenStartLine() != startLine) return removed; @@ -255,6 +265,7 @@ QList<QQmlJS::AST::SourceLocation> QmlCodeMarker::extractPragmas(QString &script startLine, startColumn)); } else return removed; +#endif } return removed; } diff --git a/src/tools/qdoc/qmlparser/qqmljsast_p.h b/src/tools/qdoc/qmlparser/qqmljsast_p.h index 9dbf4bb514..fa6b5d2488 100644 --- a/src/tools/qdoc/qmlparser/qqmljsast_p.h +++ b/src/tools/qdoc/qmlparser/qqmljsast_p.h @@ -247,7 +247,7 @@ class QML_PARSER_EXPORT ExpressionNode: public Node public: ExpressionNode() {} - virtual ExpressionNode *expressionCast() Q_DECL_OVERRIDE; + virtual ExpressionNode *expressionCast(); }; class QML_PARSER_EXPORT Statement: public Node @@ -255,7 +255,7 @@ class QML_PARSER_EXPORT Statement: public Node public: Statement() {} - virtual Statement *statementCast() Q_DECL_OVERRIDE; + virtual Statement *statementCast(); }; class QML_PARSER_EXPORT NestedExpression: public ExpressionNode @@ -267,12 +267,12 @@ public: : expression(expression) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return lparenToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return rparenToken; } // attributes @@ -288,12 +288,12 @@ public: ThisExpression() { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return thisToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return thisToken; } // attributes @@ -308,12 +308,12 @@ public: IdentifierExpression(const QStringRef &n): name (n) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return identifierToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return identifierToken; } // attributes @@ -328,12 +328,12 @@ public: NullExpression() { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return nullToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return nullToken; } // attributes @@ -347,12 +347,12 @@ public: TrueLiteral() { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return trueToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return trueToken; } // attributes @@ -366,12 +366,12 @@ public: FalseLiteral() { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return falseToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return falseToken; } // attributes @@ -386,12 +386,12 @@ public: NumericLiteral(double v): value(v) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return literalToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return literalToken; } // attributes: @@ -407,12 +407,12 @@ public: StringLiteral(const QStringRef &v): value (v) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return literalToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return literalToken; } // attributes: @@ -428,12 +428,12 @@ public: RegExpLiteral(const QStringRef &p, int f): pattern (p), flags (f) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return literalToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return literalToken; } // attributes: @@ -459,12 +459,12 @@ public: elements (elts), elision (e) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return lbracketToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return rbracketToken; } // attributes @@ -486,12 +486,12 @@ public: ObjectLiteral(PropertyAssignmentList *plist): properties (plist) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return lbraceToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return rbraceToken; } // attributes @@ -515,12 +515,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return commaToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return next ? next->lastSourceLocation() : commaToken; } inline Elision *finish () @@ -559,16 +559,16 @@ public: return front; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { if (elision) return elision->firstSourceLocation(); return expression->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { if (next) return next->lastSourceLocation(); @@ -589,12 +589,14 @@ public: PropertyName() { kind = K; } - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return propertyNameToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return propertyNameToken; } + virtual QString asString() const = 0; + // attributes SourceLocation propertyNameToken; }; @@ -602,7 +604,11 @@ public: class QML_PARSER_EXPORT PropertyAssignment: public Node { public: - PropertyAssignment() {} + PropertyAssignment(PropertyName *n) + : name(n) + {} +// attributes + PropertyName *name; }; class QML_PARSER_EXPORT PropertyAssignmentList: public Node @@ -630,12 +636,12 @@ public: return front; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return assignment->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return next ? next->lastSourceLocation() : assignment->lastSourceLocation(); } // attributes @@ -650,19 +656,18 @@ public: QQMLJS_DECLARE_AST_NODE(PropertyNameAndValue) PropertyNameAndValue(PropertyName *n, ExpressionNode *v) - : name(n), value(v) + : PropertyAssignment(n), value(v) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return name->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return value->lastSourceLocation(); } // attributes - PropertyName *name; SourceLocation colonToken; ExpressionNode *value; SourceLocation commaToken; @@ -679,25 +684,24 @@ public: }; PropertyGetterSetter(PropertyName *n, FunctionBody *b) - : type(Getter), name(n), formals(0), functionBody (b) + : PropertyAssignment(n), type(Getter), formals(0), functionBody (b) { kind = K; } PropertyGetterSetter(PropertyName *n, FormalParameterList *f, FunctionBody *b) - : type(Setter), name(n), formals(f), functionBody (b) + : PropertyAssignment(n), type(Setter), formals(f), functionBody (b) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return getSetToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return rbraceToken; } // attributes Type type; SourceLocation getSetToken; - PropertyName *name; SourceLocation lparenToken; FormalParameterList *formals; SourceLocation rparenToken; @@ -714,7 +718,9 @@ public: IdentifierPropertyName(const QStringRef &n): id (n) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); + + virtual QString asString() const { return id.toString(); } // attributes QStringRef id; @@ -728,7 +734,9 @@ public: StringLiteralPropertyName(const QStringRef &n): id (n) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); + + virtual QString asString() const { return id.toString(); } // attributes QStringRef id; @@ -742,7 +750,9 @@ public: NumericLiteralPropertyName(double n): id (n) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); + + virtual QString asString() const { return QString::number(id, 'g', 16); } // attributes double id; @@ -757,12 +767,12 @@ public: base (b), expression (e) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return base->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return rbracketToken; } // attributes @@ -781,12 +791,12 @@ public: base (b), name (n) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return base->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return identifierToken; } // attributes @@ -805,12 +815,12 @@ public: base (b), arguments (a) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return newToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return rparenToken; } // attributes @@ -829,12 +839,12 @@ public: NewExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return newToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return expression->lastSourceLocation(); } // attributes @@ -851,12 +861,12 @@ public: base (b), arguments (a) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return base->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return rparenToken; } // attributes @@ -883,12 +893,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return expression->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { if (next) return next->lastSourceLocation(); @@ -916,12 +926,12 @@ public: PostIncrementExpression(ExpressionNode *b): base (b) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return base->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return incrementToken; } // attributes @@ -937,12 +947,12 @@ public: PostDecrementExpression(ExpressionNode *b): base (b) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return base->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return decrementToken; } // attributes @@ -958,12 +968,12 @@ public: DeleteExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return deleteToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return expression->lastSourceLocation(); } // attributes @@ -979,12 +989,12 @@ public: VoidExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return voidToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return expression->lastSourceLocation(); } // attributes @@ -1000,12 +1010,12 @@ public: TypeOfExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return typeofToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return expression->lastSourceLocation(); } // attributes @@ -1021,12 +1031,12 @@ public: PreIncrementExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return incrementToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return expression->lastSourceLocation(); } // attributes @@ -1042,12 +1052,12 @@ public: PreDecrementExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return decrementToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return expression->lastSourceLocation(); } // attributes @@ -1063,12 +1073,12 @@ public: UnaryPlusExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return plusToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return expression->lastSourceLocation(); } // attributes @@ -1084,12 +1094,12 @@ public: UnaryMinusExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return minusToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return expression->lastSourceLocation(); } // attributes @@ -1105,12 +1115,12 @@ public: TildeExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return tildeToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return expression->lastSourceLocation(); } // attributes @@ -1126,12 +1136,12 @@ public: NotExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return notToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return expression->lastSourceLocation(); } // attributes @@ -1148,14 +1158,14 @@ public: left (l), op (o), right (r) { kind = K; } - virtual BinaryExpression *binaryExpressionCast() Q_DECL_OVERRIDE; + virtual BinaryExpression *binaryExpressionCast(); - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return left->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return right->lastSourceLocation(); } // attributes @@ -1174,12 +1184,12 @@ public: expression (e), ok (t), ko (f) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return expression->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return ko->lastSourceLocation(); } // attributes @@ -1198,12 +1208,12 @@ public: Expression(ExpressionNode *l, ExpressionNode *r): left (l), right (r) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return left->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return right->lastSourceLocation(); } // attributes @@ -1220,12 +1230,12 @@ public: Block(StatementList *slist): statements (slist) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return lbraceToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return rbraceToken; } // attributes @@ -1251,12 +1261,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return statement->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return next ? next->lastSourceLocation() : statement->lastSourceLocation(); } inline StatementList *finish () @@ -1280,12 +1290,12 @@ public: declarations (vlist) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return declarationKindToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return semicolonToken; } // attributes @@ -1303,12 +1313,12 @@ public: name (n), expression (e), readOnly(false) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return identifierToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return expression ? expression->lastSourceLocation() : identifierToken; } // attributes @@ -1335,12 +1345,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return declaration->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { if (next) return next->lastSourceLocation(); @@ -1372,12 +1382,12 @@ public: EmptyStatement() { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return semicolonToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return semicolonToken; } // attributes @@ -1392,12 +1402,12 @@ public: ExpressionStatement(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return expression->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return semicolonToken; } // attributes @@ -1414,12 +1424,12 @@ public: expression (e), ok (t), ko (f) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return ifToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { if (ko) return ko->lastSourceLocation(); @@ -1446,12 +1456,12 @@ public: statement (stmt), expression (e) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return doToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return semicolonToken; } // attributes @@ -1473,12 +1483,12 @@ public: expression (e), statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return whileToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return statement->lastSourceLocation(); } // attributes @@ -1498,12 +1508,12 @@ public: initialiser (i), condition (c), expression (e), statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return forToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return statement->lastSourceLocation(); } // attributes @@ -1527,12 +1537,12 @@ public: declarations (vlist), condition (c), expression (e), statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return forToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return statement->lastSourceLocation(); } // attributes @@ -1557,12 +1567,12 @@ public: initialiser (i), expression (e), statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return forToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return statement->lastSourceLocation(); } // attributes @@ -1584,12 +1594,12 @@ public: declaration (v), expression (e), statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return forToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return statement->lastSourceLocation(); } // attributes @@ -1611,12 +1621,12 @@ public: ContinueStatement(const QStringRef &l = QStringRef()): label (l) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return continueToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return semicolonToken; } // attributes @@ -1634,12 +1644,12 @@ public: BreakStatement(const QStringRef &l): label (l) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return breakToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return semicolonToken; } // attributes @@ -1657,12 +1667,12 @@ public: ReturnStatement(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return returnToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return semicolonToken; } // attributes @@ -1680,12 +1690,12 @@ public: expression (e), statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return withToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return statement->lastSourceLocation(); } // attributes @@ -1705,12 +1715,12 @@ public: clauses (c), defaultClause (d), moreClauses (r) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return lbraceToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return rbraceToken; } // attributes @@ -1730,12 +1740,12 @@ public: expression (e), block (b) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return switchToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return block->rbraceToken; } // attributes @@ -1755,12 +1765,12 @@ public: expression (e), statements (slist) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return caseToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return statements ? statements->lastSourceLocation() : colonToken; } // attributes @@ -1787,12 +1797,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return clause->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return next ? next->lastSourceLocation() : clause->lastSourceLocation(); } inline CaseClauses *finish () @@ -1816,12 +1826,12 @@ public: statements (slist) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return defaultToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return statements ? statements->lastSourceLocation() : colonToken; } // attributes @@ -1839,12 +1849,12 @@ public: label (l), statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return identifierToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return statement->lastSourceLocation(); } // attributes @@ -1862,12 +1872,12 @@ public: ThrowStatement(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return throwToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return semicolonToken; } // attributes @@ -1885,12 +1895,12 @@ public: name (n), statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return catchToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return statement->lastSourceLocation(); } // attributes @@ -1911,12 +1921,12 @@ public: statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return finallyToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return statement ? statement->lastSourceLocation() : finallyToken; } // attributes @@ -1941,12 +1951,12 @@ public: statement (stmt), catchExpression (c), finallyExpression (0) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return tryToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { if (finallyExpression) return finallyExpression->statement->rbraceToken; @@ -1972,12 +1982,12 @@ public: name (n), formals (f), body (b) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return functionToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return rbraceToken; } // attributes @@ -2001,7 +2011,7 @@ public: FunctionExpression(n, f, b) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); }; class QML_PARSER_EXPORT FormalParameterList: public Node @@ -2021,12 +2031,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return identifierToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return next ? next->lastSourceLocation() : identifierToken; } inline FormalParameterList *finish () @@ -2069,12 +2079,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return element->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return next ? next->lastSourceLocation() : element->lastSourceLocation(); } inline SourceElements *finish () @@ -2098,12 +2108,12 @@ public: elements (elts) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return elements ? elements->firstSourceLocation() : SourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return elements ? elements->lastSourceLocation() : SourceLocation(); } // attributes @@ -2119,12 +2129,12 @@ public: elements (elts) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return elements ? elements->firstSourceLocation() : SourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return elements ? elements->lastSourceLocation() : SourceLocation(); } // attributes @@ -2140,12 +2150,12 @@ public: declaration (f) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return declaration->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return declaration->lastSourceLocation(); } // attributes @@ -2161,12 +2171,12 @@ public: statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return statement->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return statement->lastSourceLocation(); } // attributes @@ -2181,12 +2191,12 @@ public: DebuggerStatement() { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return debuggerToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return semicolonToken; } // attributes @@ -2218,12 +2228,12 @@ public: return head; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return identifierToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return next ? next->lastSourceLocation() : identifierToken; } // attributes @@ -2245,12 +2255,12 @@ public: : importUri(uri) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return importToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return semicolonToken; } // attributes @@ -2268,10 +2278,10 @@ public: class QML_PARSER_EXPORT UiObjectMember: public Node { public: - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE = 0; - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE = 0; + virtual SourceLocation firstSourceLocation() const = 0; + virtual SourceLocation lastSourceLocation() const = 0; - virtual UiObjectMember *uiObjectMemberCast() Q_DECL_OVERRIDE; + virtual UiObjectMember *uiObjectMemberCast(); }; class QML_PARSER_EXPORT UiObjectMemberList: public Node @@ -2291,12 +2301,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return member->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return next ? next->lastSourceLocation() : member->lastSourceLocation(); } UiObjectMemberList *finish() @@ -2335,12 +2345,12 @@ public: return head; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return identifierToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return next ? next->lastSourceLocation() : identifierToken; } // attributes @@ -2358,12 +2368,12 @@ public: : pragmaType(type) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return pragmaToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return semicolonToken; } // attributes @@ -2408,12 +2418,12 @@ public: return head; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return headerItem->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return next ? next->lastSourceLocation() : headerItem->lastSourceLocation(); } // attributes @@ -2430,9 +2440,9 @@ public: : headers(headers), members(members) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { if (headers) return headers->firstSourceLocation(); @@ -2441,7 +2451,7 @@ public: return SourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { if (members) return members->lastSourceLocation(); @@ -2472,12 +2482,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return member->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return next ? next->lastSourceLocation() : member->lastSourceLocation(); } UiArrayMemberList *finish() @@ -2502,12 +2512,12 @@ public: : members(members) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return lbraceToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return rbraceToken; } // attributes @@ -2533,12 +2543,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return propertyTypeToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return next ? next->lastSourceLocation() : identifierToken; } inline UiParameterList *finish () @@ -2573,9 +2583,9 @@ public: : type(Property), memberType(memberType), name(name), statement(statement), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { if (defaultToken.isValid()) return defaultToken; @@ -2585,7 +2595,7 @@ public: return propertyToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { if (binding) return binding->lastSourceLocation(); @@ -2625,12 +2635,12 @@ public: : qualifiedTypeNameId(qualifiedTypeNameId), initializer(initializer) { kind = K; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return qualifiedTypeNameId->identifierToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return initializer->rbraceToken; } // attributes @@ -2647,7 +2657,7 @@ public: : sourceElement(sourceElement) { kind = K; } - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { if (FunctionDeclaration *funDecl = cast<FunctionDeclaration *>(sourceElement)) return funDecl->firstSourceLocation(); @@ -2657,7 +2667,7 @@ public: return SourceLocation(); } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { if (FunctionDeclaration *funDecl = cast<FunctionDeclaration *>(sourceElement)) return funDecl->lastSourceLocation(); @@ -2667,7 +2677,7 @@ public: return SourceLocation(); } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); // attributes @@ -2688,7 +2698,7 @@ public: hasOnToken(false) { kind = K; } - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { if (hasOnToken && qualifiedTypeNameId) return qualifiedTypeNameId->identifierToken; @@ -2696,10 +2706,10 @@ public: return qualifiedId->identifierToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return initializer->rbraceToken; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); // attributes @@ -2721,13 +2731,13 @@ public: statement(statement) { kind = K; } - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return qualifiedId->identifierToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return statement->lastSourceLocation(); } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); // attributes UiQualifiedId *qualifiedId; @@ -2746,13 +2756,13 @@ public: members(members) { kind = K; } - virtual SourceLocation firstSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation firstSourceLocation() const { return qualifiedId->identifierToken; } - virtual SourceLocation lastSourceLocation() const Q_DECL_OVERRIDE + virtual SourceLocation lastSourceLocation() const { return rbracketToken; } - virtual void accept0(Visitor *visitor) Q_DECL_OVERRIDE; + virtual void accept0(Visitor *visitor); // attributes UiQualifiedId *qualifiedId; diff --git a/src/tools/qdoc/qmlparser/qqmljsastfwd_p.h b/src/tools/qdoc/qmlparser/qqmljsastfwd_p.h index c4cb59293d..eae4125ab2 100644 --- a/src/tools/qdoc/qmlparser/qqmljsastfwd_p.h +++ b/src/tools/qdoc/qmlparser/qqmljsastfwd_p.h @@ -56,7 +56,7 @@ namespace QQmlJS { namespace AST { class SourceLocation { public: - SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0) + explicit SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0) : offset(offset), length(length), startLine(line), startColumn(column) { } diff --git a/src/tools/qdoc/qmlparser/qqmljsengine_p.cpp b/src/tools/qdoc/qmlparser/qqmljsengine_p.cpp index faf05f71f1..1c0a70a372 100644 --- a/src/tools/qdoc/qmlparser/qqmljsengine_p.cpp +++ b/src/tools/qdoc/qmlparser/qqmljsengine_p.cpp @@ -114,7 +114,7 @@ double integerFromString(const QString &str, int radix) Engine::Engine() - : _lexer(0) + : _lexer(0), _directives(0) { } Engine::~Engine() @@ -135,6 +135,12 @@ Lexer *Engine::lexer() const void Engine::setLexer(Lexer *lexer) { _lexer = lexer; } +Directives *Engine::directives() const +{ return _directives; } + +void Engine::setDirectives(Directives *directives) +{ _directives = directives; } + MemoryPool *Engine::pool() { return &_pool; } diff --git a/src/tools/qdoc/qmlparser/qqmljsengine_p.h b/src/tools/qdoc/qmlparser/qqmljsengine_p.h index 210797ffcd..fb65d7f028 100644 --- a/src/tools/qdoc/qmlparser/qqmljsengine_p.h +++ b/src/tools/qdoc/qmlparser/qqmljsengine_p.h @@ -57,6 +57,7 @@ QT_QML_BEGIN_NAMESPACE namespace QQmlJS { class Lexer; +class Directives; class MemoryPool; class QML_PARSER_EXPORT DiagnosticMessage @@ -84,6 +85,7 @@ public: class QML_PARSER_EXPORT Engine { Lexer *_lexer; + Directives *_directives; MemoryPool _pool; QList<AST::SourceLocation> _comments; QString _extraCode; @@ -102,6 +104,9 @@ public: Lexer *lexer() const; void setLexer(Lexer *lexer); + Directives *directives() const; + void setDirectives(Directives *directives); + MemoryPool *pool(); inline QStringRef midRef(int position, int size) { return _code.midRef(position, size); } diff --git a/src/tools/qdoc/qmlparser/qqmljsglobal_p.h b/src/tools/qdoc/qmlparser/qqmljsglobal_p.h index c9b5b4c5b4..fe2cbe7d1d 100644 --- a/src/tools/qdoc/qmlparser/qqmljsglobal_p.h +++ b/src/tools/qdoc/qmlparser/qqmljsglobal_p.h @@ -33,17 +33,6 @@ #ifndef QQMLJSGLOBAL_P_H #define QQMLJSGLOBAL_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 <QtCore/qglobal.h> #ifdef QT_CREATOR @@ -65,9 +54,9 @@ // QmlDevTools is a static library # define QML_PARSER_EXPORT # elif defined(QT_BUILD_QML_LIB) -# define QML_PARSER_EXPORT Q_AUTOTEST_EXPORT +# define QML_PARSER_EXPORT Q_DECL_EXPORT # else -# define QML_PARSER_EXPORT +# define QML_PARSER_EXPORT Q_DECL_IMPORT # endif #endif // QT_CREATOR diff --git a/src/tools/qdoc/qmlparser/qqmljslexer.cpp b/src/tools/qdoc/qmlparser/qqmljslexer.cpp index 69dcb15794..62748ef10d 100644 --- a/src/tools/qdoc/qmlparser/qqmljslexer.cpp +++ b/src/tools/qdoc/qmlparser/qqmljslexer.cpp @@ -887,8 +887,7 @@ again: int Lexer::scanNumber(QChar ch) { if (ch != QLatin1Char('0')) { - QByteArray buf; - buf.reserve(64); + QVarLengthArray<char, 64> buf; buf += ch.toLatin1(); QChar n = _char; @@ -1225,12 +1224,60 @@ bool Lexer::canInsertAutomaticSemicolon(int token) const || _followsClosingBrace; } -bool Lexer::scanDirectives(Directives *directives) +static const int uriTokens[] = { + QQmlJSGrammar::T_IDENTIFIER, + QQmlJSGrammar::T_PROPERTY, + QQmlJSGrammar::T_SIGNAL, + QQmlJSGrammar::T_READONLY, + QQmlJSGrammar::T_ON, + QQmlJSGrammar::T_BREAK, + QQmlJSGrammar::T_CASE, + QQmlJSGrammar::T_CATCH, + QQmlJSGrammar::T_CONTINUE, + QQmlJSGrammar::T_DEFAULT, + QQmlJSGrammar::T_DELETE, + QQmlJSGrammar::T_DO, + QQmlJSGrammar::T_ELSE, + QQmlJSGrammar::T_FALSE, + QQmlJSGrammar::T_FINALLY, + QQmlJSGrammar::T_FOR, + QQmlJSGrammar::T_FUNCTION, + QQmlJSGrammar::T_IF, + QQmlJSGrammar::T_IN, + QQmlJSGrammar::T_INSTANCEOF, + QQmlJSGrammar::T_NEW, + QQmlJSGrammar::T_NULL, + QQmlJSGrammar::T_RETURN, + QQmlJSGrammar::T_SWITCH, + QQmlJSGrammar::T_THIS, + QQmlJSGrammar::T_THROW, + QQmlJSGrammar::T_TRUE, + QQmlJSGrammar::T_TRY, + QQmlJSGrammar::T_TYPEOF, + QQmlJSGrammar::T_VAR, + QQmlJSGrammar::T_VOID, + QQmlJSGrammar::T_WHILE, + QQmlJSGrammar::T_CONST, + QQmlJSGrammar::T_DEBUGGER, + QQmlJSGrammar::T_RESERVED_WORD, + QQmlJSGrammar::T_WITH, + + QQmlJSGrammar::EOF_SYMBOL +}; +static inline bool isUriToken(int token) { - if (_qmlMode) { - // the directives are a Javascript-only extension. - return false; + const int *current = uriTokens; + while (*current != QQmlJSGrammar::EOF_SYMBOL) { + if (*current == token) + return true; + ++current; } + return false; +} + +bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error) +{ + Q_ASSERT(!_qmlMode); lex(); // fetch the first token @@ -1238,24 +1285,33 @@ bool Lexer::scanDirectives(Directives *directives) return true; do { - lex(); // skip T_DOT - const int lineNumber = tokenStartLine(); + const int column = tokenStartColumn(); + + lex(); // skip T_DOT if (! (_tokenKind == T_IDENTIFIER || _tokenKind == T_RESERVED_WORD)) - return false; // expected a valid QML/JS directive + return true; // expected a valid QML/JS directive const QString directiveName = tokenText(); if (! (directiveName == QLatin1String("pragma") || - directiveName == QLatin1String("import"))) + directiveName == QLatin1String("import"))) { + error->message = QCoreApplication::translate("QQmlParser", "Syntax error"); + error->loc.startLine = tokenStartLine(); + error->loc.startColumn = tokenStartColumn(); return false; // not a valid directive name + } // it must be a pragma or an import directive. if (directiveName == QLatin1String("pragma")) { // .pragma library - if (! (lex() == T_IDENTIFIER && tokenText() == QLatin1String("library"))) + if (! (lex() == T_IDENTIFIER && tokenText() == QLatin1String("library"))) { + error->message = QCoreApplication::translate("QQmlParser", "Syntax error"); + error->loc.startLine = tokenStartLine(); + error->loc.startColumn = tokenStartColumn(); return false; // expected `library + } // we found a .pragma library directive directives->pragmaLibrary(); @@ -1274,22 +1330,53 @@ bool Lexer::scanDirectives(Directives *directives) fileImport = true; pathOrUri = tokenText(); + if (!pathOrUri.endsWith(QLatin1String("js"))) { + error->message = QCoreApplication::translate("QQmlParser","Imported file must be a script"); + error->loc.startLine = tokenStartLine(); + error->loc.startColumn = tokenStartColumn(); + return false; + } + } else if (_tokenKind == T_IDENTIFIER) { // .import T_IDENTIFIER (. T_IDENTIFIER)* T_NUMERIC_LITERAL as T_IDENTIFIER - pathOrUri = tokenText(); + while (true) { + if (!isUriToken(_tokenKind)) { + error->message = QCoreApplication::translate("QQmlParser","Invalid module URI"); + error->loc.startLine = tokenStartLine(); + error->loc.startColumn = tokenStartColumn(); + return false; + } - lex(); // skip the first T_IDENTIFIER - for (; _tokenKind == T_DOT; lex()) { - if (lex() != T_IDENTIFIER) + pathOrUri.append(tokenText()); + + lex(); + if (tokenStartLine() != lineNumber) { + error->message = QCoreApplication::translate("QQmlParser","Invalid module URI"); + error->loc.startLine = tokenStartLine(); + error->loc.startColumn = tokenStartColumn(); return false; + } + if (_tokenKind != QQmlJSGrammar::T_DOT) + break; + + pathOrUri.append(QLatin1Char('.')); - pathOrUri += QLatin1Char('.'); - pathOrUri += tokenText(); + lex(); + if (tokenStartLine() != lineNumber) { + error->message = QCoreApplication::translate("QQmlParser","Invalid module URI"); + error->loc.startLine = tokenStartLine(); + error->loc.startColumn = tokenStartColumn(); + return false; + } } - if (_tokenKind != T_NUMERIC_LITERAL) + if (_tokenKind != T_NUMERIC_LITERAL) { + error->message = QCoreApplication::translate("QQmlParser","Module import requires a version"); + error->loc.startLine = tokenStartLine(); + error->loc.startColumn = tokenStartColumn(); return false; // expected the module version number + } version = tokenText(); } @@ -1297,22 +1384,51 @@ bool Lexer::scanDirectives(Directives *directives) // // recognize the mandatory `as' followed by the module name // - if (! (lex() == T_IDENTIFIER && tokenText() == QLatin1String("as"))) + if (! (lex() == T_IDENTIFIER && tokenText() == QLatin1String("as") && tokenStartLine() == lineNumber)) { + if (fileImport) + error->message = QCoreApplication::translate("QQmlParser", "File import requires a qualifier"); + else + error->message = QCoreApplication::translate("QQmlParser", "Module import requires a qualifier"); + if (tokenStartLine() != lineNumber) { + error->loc.startLine = lineNumber; + error->loc.startColumn = column; + } else { + error->loc.startLine = tokenStartLine(); + error->loc.startColumn = tokenStartColumn(); + } return false; // expected `as' + } - if (lex() != T_IDENTIFIER) + if (lex() != T_IDENTIFIER || tokenStartLine() != lineNumber) { + if (fileImport) + error->message = QCoreApplication::translate("QQmlParser", "File import requires a qualifier"); + else + error->message = QCoreApplication::translate("QQmlParser", "Module import requires a qualifier"); + error->loc.startLine = tokenStartLine(); + error->loc.startColumn = tokenStartColumn(); return false; // expected module name + } const QString module = tokenText(); + if (!module.at(0).isUpper()) { + error->message = QCoreApplication::translate("QQmlParser","Invalid import qualifier"); + error->loc.startLine = tokenStartLine(); + error->loc.startColumn = tokenStartColumn(); + return false; + } if (fileImport) - directives->importFile(pathOrUri, module); + directives->importFile(pathOrUri, module, lineNumber, column); else - directives->importModule(pathOrUri, version, module); + directives->importModule(pathOrUri, version, module, lineNumber, column); } - if (tokenStartLine() != lineNumber) + if (tokenStartLine() != lineNumber) { + error->message = QCoreApplication::translate("QQmlParser", "Syntax error"); + error->loc.startLine = tokenStartLine(); + error->loc.startColumn = tokenStartColumn(); return false; // the directives cannot span over multiple lines + } // fetch the first token after the .pragma/.import directive lex(); diff --git a/src/tools/qdoc/qmlparser/qqmljslexer_p.h b/src/tools/qdoc/qmlparser/qqmljslexer_p.h index 20f4b42b8d..427affe4b9 100644 --- a/src/tools/qdoc/qmlparser/qqmljslexer_p.h +++ b/src/tools/qdoc/qmlparser/qqmljslexer_p.h @@ -55,6 +55,7 @@ QT_QML_BEGIN_NAMESPACE namespace QQmlJS { class Engine; +class DiagnosticMessage; class QML_PARSER_EXPORT Directives { public: @@ -64,17 +65,21 @@ public: { } - virtual void importFile(const QString &jsfile, const QString &module) + virtual void importFile(const QString &jsfile, const QString &module, int line, int column) { Q_UNUSED(jsfile); Q_UNUSED(module); + Q_UNUSED(line); + Q_UNUSED(column); } - virtual void importModule(const QString &uri, const QString &version, const QString &module) + virtual void importModule(const QString &uri, const QString &version, const QString &module, int line, int column) { Q_UNUSED(uri); Q_UNUSED(version); Q_UNUSED(module); + Q_UNUSED(line); + Q_UNUSED(column); } }; @@ -146,7 +151,7 @@ public: int lex(); bool scanRegExp(RegExpBodyPrefix prefix = NoPrefix); - bool scanDirectives(Directives *directives); + bool scanDirectives(Directives *directives, DiagnosticMessage *error); int regExpFlags() const { return _patternFlags; } QString regExpPattern() const { return _tokenText; } diff --git a/src/tools/qdoc/qmlparser/qqmljsmemorypool_p.h b/src/tools/qdoc/qmlparser/qqmljsmemorypool_p.h index f8bb70c54c..16927251c7 100644 --- a/src/tools/qdoc/qmlparser/qqmljsmemorypool_p.h +++ b/src/tools/qdoc/qmlparser/qqmljsmemorypool_p.h @@ -57,6 +57,8 @@ QT_QML_BEGIN_NAMESPACE namespace QQmlJS { +class Managed; + class QML_PARSER_EXPORT MemoryPool : public QSharedData { MemoryPool(const MemoryPool &other); @@ -100,6 +102,30 @@ public: _ptr = _end = 0; } + template <typename _Tp> _Tp *New() { return new (this->allocate(sizeof(_Tp))) _Tp(); } + + template <typename PoolContentType, typename Visitor> + void visitManagedPool(Visitor &visitor) + { + for (int i = 0; i <= _blockCount; ++i) { + char *p = _blocks[i]; + char *end = p + BLOCK_SIZE; + if (i == _blockCount) { + Q_ASSERT(_ptr <= end); + end = _ptr; + } + + Q_ASSERT(p <= end); + + const qptrdiff increment = (sizeof(PoolContentType) + 7) & ~7; + + while (p + increment <= end) { + visitor(reinterpret_cast<PoolContentType*>(p)); + p += increment; + } + } + } + private: void *allocate_helper(size_t size) { diff --git a/src/tools/qdoc/qmlparser/qqmljsparser.cpp b/src/tools/qdoc/qmlparser/qqmljsparser.cpp index 44279260d7..520c377034 100644 --- a/src/tools/qdoc/qmlparser/qqmljsparser.cpp +++ b/src/tools/qdoc/qmlparser/qqmljsparser.cpp @@ -161,7 +161,24 @@ bool Parser::parse(int startToken) token_buffer[0].token = startToken; first_token = &token_buffer[0]; - last_token = &token_buffer[1]; + if (startToken == T_FEED_JS_PROGRAM && !lexer->qmlMode()) { + Directives ignoreDirectives; + Directives *directives = driver->directives(); + if (!directives) + directives = &ignoreDirectives; + DiagnosticMessage error; + if (!lexer->scanDirectives(directives, &error)) { + diagnostic_messages.append(error); + return false; + } + token_buffer[1].token = lexer->tokenKind(); + token_buffer[1].dval = lexer->tokenValue(); + token_buffer[1].loc = location(lexer); + token_buffer[1].spell = lexer->tokenSpell(); + last_token = &token_buffer[2]; + } else { + last_token = &token_buffer[1]; + } tos = -1; program = 0; diff --git a/src/tools/qdoc/qmlvisitor.cpp b/src/tools/qdoc/qmlvisitor.cpp index 6179e80085..190c9f0444 100644 --- a/src/tools/qdoc/qmlvisitor.cpp +++ b/src/tools/qdoc/qmlvisitor.cpp @@ -42,6 +42,7 @@ #include "codeparser.h" #include "qmlvisitor.h" #include "qdocdatabase.h" +#include "tokenizer.h" QT_BEGIN_NAMESPACE @@ -146,6 +147,29 @@ QQmlJS::AST::SourceLocation QmlDocVisitor::precedingComment(quint32 offset) cons return QQmlJS::AST::SourceLocation(); } +class QmlSignatureParser +{ + public: + QmlSignatureParser(FunctionNode* func, const QString& signature, const Location& loc); + void readToken() { tok_ = tokenizer_->getToken(); } + QString lexeme() { return tokenizer_->lexeme(); } + QString previousLexeme() { return tokenizer_->previousLexeme(); } + + bool match(int target); + bool matchDataType(CodeChunk* dataType, QString* var); + bool matchParameter(); + bool matchFunctionDecl(); + + private: + QString signature_; + QStringList names_; + QString funcName_; + Tokenizer* tokenizer_; + int tok_; + FunctionNode* func_; + const Location& location_; +}; + /*! Finds the nearest unused qdoc comment above the QML entity represented by the \a node and processes the qdoc commands @@ -216,6 +240,13 @@ bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Nod else qDebug() << " FAILED TO PARSE QML OR JS PROPERTY:" << topic << args; } + else if ((topic == COMMAND_QMLMETHOD) || (topic == COMMAND_QMLATTACHEDMETHOD) || + (topic == COMMAND_JSMETHOD) || (topic == COMMAND_JSATTACHEDMETHOD)) { + if (node->isFunction()) { + FunctionNode* fn = static_cast<FunctionNode*>(node); + QmlSignatureParser qsp(fn, args, doc.location()); + } + } } } for (int i=0; i<nodes.size(); ++i) @@ -232,6 +263,174 @@ bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Nod return false; } +QmlSignatureParser::QmlSignatureParser(FunctionNode* func, const QString& signature, const Location& loc) + : signature_(signature), func_(func), location_(loc) +{ + QByteArray latin1 = signature.toLatin1(); + Tokenizer stringTokenizer(location_, latin1); + stringTokenizer.setParsingFnOrMacro(true); + tokenizer_ = &stringTokenizer; + readToken(); + matchFunctionDecl(); +} + +/*! + If the current token matches \a target, read the next + token and return true. Otherwise, don't read the next + token, and return false. + */ +bool QmlSignatureParser::match(int target) +{ + if (tok_ == target) { + readToken(); + return true; + } + return false; +} + +/*! + Parse a QML data type into \a dataType and an optional + variable name into \a var. + */ +bool QmlSignatureParser::matchDataType(CodeChunk* dataType, QString* var) +{ + /* + This code is really hard to follow... sorry. The loop is there to match + Alpha::Beta::Gamma::...::Omega. + */ + for (;;) { + bool virgin = true; + + if (tok_ != Tok_Ident) { + while (match(Tok_signed) || + match(Tok_unsigned) || + match(Tok_short) || + match(Tok_long) || + match(Tok_int64)) { + dataType->append(previousLexeme()); + virgin = false; + } + } + + if (virgin) { + if (match(Tok_Ident)) { + dataType->append(previousLexeme()); + } + else if (match(Tok_void) || + match(Tok_int) || + match(Tok_char) || + match(Tok_double) || + match(Tok_Ellipsis)) + dataType->append(previousLexeme()); + else + return false; + } + else if (match(Tok_int) || + match(Tok_char) || + match(Tok_double)) { + dataType->append(previousLexeme()); + } + + if (match(Tok_Gulbrandsen)) + dataType->append(previousLexeme()); + else + break; + } + + while (match(Tok_Ampersand) || + match(Tok_Aster) || + match(Tok_const) || + match(Tok_Caret)) + dataType->append(previousLexeme()); + + /* + The usual case: Look for an optional identifier, then for + some array brackets. + */ + dataType->appendHotspot(); + + if ((var != 0) && match(Tok_Ident)) + *var = previousLexeme(); + + if (tok_ == Tok_LeftBracket) { + int bracketDepth0 = tokenizer_->bracketDepth(); + while ((tokenizer_->bracketDepth() >= bracketDepth0 && tok_ != Tok_Eoi) || + tok_ == Tok_RightBracket) { + dataType->append(lexeme()); + readToken(); + } + } + return true; +} + +bool QmlSignatureParser::matchParameter() +{ + QString name; + CodeChunk dataType; + CodeChunk defaultValue; + + bool result = matchDataType(&dataType, &name); + if (name.isEmpty()) { + name = dataType.toString(); + dataType.clear(); + } + + if (!result) + return false; + if (match(Tok_Equal)) { + int parenDepth0 = tokenizer_->parenDepth(); + while (tokenizer_->parenDepth() >= parenDepth0 && + (tok_ != Tok_Comma || + tokenizer_->parenDepth() > parenDepth0) && + tok_ != Tok_Eoi) { + defaultValue.append(lexeme()); + readToken(); + } + } + func_->addParameter(Parameter(dataType.toString(), "", name, defaultValue.toString())); + return true; +} + +bool QmlSignatureParser::matchFunctionDecl() +{ + CodeChunk returnType; + + int firstBlank = signature_.indexOf(QChar(' ')); + int leftParen = signature_.indexOf(QChar('(')); + if ((firstBlank > 0) && (leftParen - firstBlank) > 1) { + if (!matchDataType(&returnType, 0)) + return false; + } + + while (match(Tok_Ident)) { + names_.append(previousLexeme()); + if (!match(Tok_Gulbrandsen)) { + funcName_ = previousLexeme(); + names_.pop_back(); + break; + } + } + + if (tok_ != Tok_LeftParen) + return false; + + readToken(); + + func_->setLocation(location_); + func_->setReturnType(returnType.toString()); + + if (tok_ != Tok_RightParen) { + func_->clearParams(); + do { + if (!matchParameter()) + return false; + } while (match(Tok_Comma)); + } + if (!match(Tok_RightParen)) + return false; + return true; +} + /*! A QML property argument has the form... diff --git a/src/tools/qdoc/tree.cpp b/src/tools/qdoc/tree.cpp index 6393ad4e6f..d36003c665 100644 --- a/src/tools/qdoc/tree.cpp +++ b/src/tools/qdoc/tree.cpp @@ -178,7 +178,7 @@ FunctionNode* Tree::findFunctionNode(const QStringList& parentPath, const Functi parent = findNode(parentPath, 0, 0, Node::DontCare); if (parent == 0 || !parent->isInnerNode()) return 0; - return ((InnerNode*)parent)->findFunctionNode(clone); + return ((const InnerNode*)parent)->findFunctionNode(clone); } @@ -249,9 +249,9 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& path, const Node* next; if (i == path.size() - 1) - next = ((InnerNode*) node)->findFunctionNode(path.at(i)); + next = ((const InnerNode*) node)->findFunctionNode(path.at(i)); else - next = ((InnerNode*) node)->findChildNode(path.at(i), genus); + next = ((const InnerNode*) node)->findChildNode(path.at(i), genus); if (!next && node->isClass() && (findFlags & SearchBaseClasses)) { NodeList baseClasses = allBaseClasses(static_cast<const ClassNode*>(node)); diff --git a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc index b51ab21b25..8dbc716027 100644 --- a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc +++ b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc @@ -132,8 +132,6 @@ Since Qt 4.5, Qt style sheets fully supports Mac OS X. - \warning Qt style sheets are currently not supported for custom QStyle - subclasses. We plan to address this in some future release. */ /*! diff --git a/src/widgets/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp index d1bd0e657e..1cc3a2a905 100644 --- a/src/widgets/itemviews/qfileiconprovider.cpp +++ b/src/widgets/itemviews/qfileiconprovider.cpp @@ -39,6 +39,7 @@ #include <qpixmapcache.h> #include <private/qfunctions_p.h> #include <private/qguiapplication_p.h> +#include <private/qicon_p.h> #include <qpa/qplatformintegration.h> #include <qpa/qplatformservices.h> #include <qpa/qplatformtheme.h> @@ -57,6 +58,105 @@ QT_BEGIN_NAMESPACE +static bool isCacheable(const QFileInfo &fi); + +class QFileIconEngine : public QPixmapIconEngine +{ +public: + QFileIconEngine(const QFileIconProvider *fip, const QFileInfo &info) + : QPixmapIconEngine(), m_fileIconProvider(fip), m_fileInfo(info) + { } + + QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE + { + Q_UNUSED(mode); + Q_UNUSED(state); + QPixmap pixmap; + + if (!size.isValid()) + return pixmap; + + const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme(); + if (!theme) + return pixmap; + + const QString &keyBase = QLatin1String("qt_.") + m_fileInfo.suffix().toUpper(); + + bool cacheable = isCacheable(m_fileInfo); + if (cacheable) { + QPixmapCache::find(keyBase + QString::number(size.width()), pixmap); + if (!pixmap.isNull()) + return pixmap; + } + + QPlatformTheme::IconOptions iconOptions; + if (m_fileIconProvider->options() & QFileIconProvider::DontUseCustomDirectoryIcons) + iconOptions |= QPlatformTheme::DontUseCustomDirectoryIcons; + + pixmap = theme->fileIconPixmap(m_fileInfo, size, iconOptions); + if (!pixmap.isNull()) { + if (cacheable) + QPixmapCache::insert(keyBase + QString::number(size.width()), pixmap); + } + + return pixmap; + } + + QList<QSize> availableSizes(QIcon::Mode mode = QIcon::Normal, QIcon::State state = QIcon::Off) const Q_DECL_OVERRIDE + { + Q_UNUSED(mode); + Q_UNUSED(state); + static QList<QSize> sizes; + static QPlatformTheme *theme = 0; + if (!theme) { + theme = QGuiApplicationPrivate::platformTheme(); + if (!theme) + return sizes; + + QList<int> themeSizes = theme->themeHint(QPlatformTheme::IconPixmapSizes).value<QList<int> >(); + if (themeSizes.isEmpty()) + return sizes; + + foreach (int size, themeSizes) + sizes << QSize(size, size); + } + return sizes; + } + + QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE + { + const QList<QSize> &sizes = availableSizes(mode, state); + const int numberSizes = sizes.length(); + if (numberSizes == 0) + return QSize(); + + // Find the smallest available size whose area is still larger than the input + // size. Otherwise, use the largest area available size. (We don't assume the + // platform theme sizes are sorted, hence the extra logic.) + const int sizeArea = size.width() * size.height(); + QSize actualSize = sizes.first(); + int actualArea = actualSize.width() * actualSize.height(); + for (int i = 1; i < numberSizes; ++i) { + const QSize &s = sizes.at(i); + const int a = s.width() * s.height(); + if ((sizeArea <= a && a < actualArea) || (actualArea < sizeArea && actualArea < a)) { + actualSize = s; + actualArea = a; + } + } + + if (!actualSize.isNull() && (actualSize.width() > size.width() || actualSize.height() > size.height())) + actualSize.scale(size, Qt::KeepAspectRatio); + + return actualSize; + } + +private: + const QFileIconProvider *m_fileIconProvider; + QFileInfo m_fileInfo; +}; + + /*! \class QFileIconProvider @@ -86,8 +186,8 @@ QT_BEGIN_NAMESPACE cause a big performance impact over network or removable drives. */ -QFileIconProviderPrivate::QFileIconProviderPrivate() : - homePath(QDir::home().absolutePath()) +QFileIconProviderPrivate::QFileIconProviderPrivate(QFileIconProvider *q) : + q_ptr(q), homePath(QDir::home().absolutePath()) { } @@ -153,7 +253,7 @@ QIcon QFileIconProviderPrivate::getIcon(QStyle::StandardPixmap name) const */ QFileIconProvider::QFileIconProvider() - : d_ptr(new QFileIconProviderPrivate) + : d_ptr(new QFileIconProviderPrivate(this)) { } @@ -238,53 +338,18 @@ static bool isCacheable(const QFileInfo &fi) QIcon QFileIconProviderPrivate::getIcon(const QFileInfo &fi) const { - QIcon retIcon; const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme(); if (!theme) - return retIcon; + return QIcon(); QList<int> sizes = theme->themeHint(QPlatformTheme::IconPixmapSizes).value<QList<int> >(); if (sizes.isEmpty()) - return retIcon; - - const QString keyBase = QLatin1String("qt_.") + fi.suffix().toUpper(); - - bool cacheable = isCacheable(fi); - if (cacheable) { - QPixmap pixmap; - QPixmapCache::find(keyBase + QString::number(sizes.at(0)), pixmap); - if (!pixmap.isNull()) { - bool iconIsComplete = true; - retIcon.addPixmap(pixmap); - for (int i = 1; i < sizes.count(); i++) - if (QPixmapCache::find(keyBase + QString::number(sizes.at(i)), pixmap)) { - retIcon.addPixmap(pixmap); - } else { - iconIsComplete = false; - break; - } - if (iconIsComplete) - return retIcon; - } - } - - QPlatformTheme::IconOptions iconOptions; - if (options & QFileIconProvider::DontUseCustomDirectoryIcons) - iconOptions |= QPlatformTheme::DontUseCustomDirectoryIcons; - - Q_FOREACH (int size, sizes) { - QPixmap pixmap = theme->fileIconPixmap(fi, QSizeF(size, size), iconOptions); - if (!pixmap.isNull()) { - retIcon.addPixmap(pixmap); - if (cacheable) - QPixmapCache::insert(keyBase + QString::number(size), pixmap); - } - } + return QIcon(); - return retIcon; + Q_Q(const QFileIconProvider); + return QIcon(new QFileIconEngine(q, fi)); } - /*! Returns an icon for the file described by \a info. */ diff --git a/src/widgets/itemviews/qfileiconprovider_p.h b/src/widgets/itemviews/qfileiconprovider_p.h index 213535616c..a1fb4acbea 100644 --- a/src/widgets/itemviews/qfileiconprovider_p.h +++ b/src/widgets/itemviews/qfileiconprovider_p.h @@ -60,7 +60,7 @@ class QFileIconProviderPrivate Q_DECLARE_PUBLIC(QFileIconProvider) public: - QFileIconProviderPrivate(); + QFileIconProviderPrivate(QFileIconProvider *q); QIcon getIcon(QStyle::StandardPixmap name) const; QIcon getIcon(const QFileInfo &fi) const; diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index f63685c37a..3b33894627 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -768,6 +768,7 @@ void QOpenGLWidgetPrivate::resolveSamples() q->makeCurrent(); QRect rect(QPoint(0, 0), fbo->size()); QOpenGLFramebufferObject::blitFramebuffer(resolvedFbo, rect, fbo, rect); + QOpenGLContext::currentContext()->functions()->glFlush(); } } diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp index c4326aaa5a..c08c4eeb32 100644 --- a/src/widgets/kernel/qshortcut.cpp +++ b/src/widgets/kernel/qshortcut.cpp @@ -44,6 +44,7 @@ #include <private/qshortcutmap_p.h> #include <private/qaction_p.h> #include <private/qwidgetwindow_p.h> +#include <qpa/qplatformmenu.h> QT_BEGIN_NAMESPACE @@ -269,9 +270,13 @@ static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidge // On Mac, menu item shortcuts are processed before reaching any window. // That means that if a menu action shortcut has not been already processed // (and reaches this point), then the menu item itself has been disabled. - // This occurs at the QPA level on Mac, were we disable all the Cocoa menus - // when showing a modal window. - if (a->shortcut().count() < 1 || (a->shortcut().count() == 1 && (a->shortcut()[0] & Qt::MODIFIER_MASK) != 0)) + // This occurs at the QPA level on Mac, where we disable all the Cocoa menus + // when showing a modal window. (Notice that only the QPA menu is disabled, + // not the QMenu.) Since we can also reach this code by climbing the menu + // hierarchy (see below), or when the shortcut is not a key-equivalent, we + // need to check whether the QPA menu is actually disabled. + QPlatformMenu *pm = menu->platformMenu(); + if (!pm || !pm->isEnabled()) continue; #endif QAction *a = menu->menuAction(); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 6d8bad3149..07a39234ef 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -7144,14 +7144,16 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) bool needsShow = false; - if (!(data.window_state & Qt::WindowFullScreen) && (w == 0 || h == 0)) { - q->setAttribute(Qt::WA_OutsideWSRange, true); - if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) - hide_sys(); - data.crect = QRect(x, y, w, h); - } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) { - q->setAttribute(Qt::WA_OutsideWSRange, false); - needsShow = true; + if (q->isWindow()) { + if (!(data.window_state & Qt::WindowFullScreen) && (w == 0 || h == 0)) { + q->setAttribute(Qt::WA_OutsideWSRange, true); + if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) + hide_sys(); + data.crect = QRect(x, y, w, h); + } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) { + q->setAttribute(Qt::WA_OutsideWSRange, false); + needsShow = true; + } } if (q->isVisible()) { diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index b7ffc20c8e..12f5d4b8b0 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -554,7 +554,8 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) &qt_button_down, qt_last_mouse_receiver); } #ifndef QT_NO_CONTEXTMENU - if (event->type() == contextMenuTrigger && event->button() == Qt::RightButton) { + if (event->type() == contextMenuTrigger && event->button() == Qt::RightButton + && m_widget->rect().contains(event->pos())) { QContextMenuEvent e(QContextMenuEvent::Mouse, mapped, event->globalPos(), event->modifiers()); QGuiApplication::sendSpontaneousEvent(receiver, &e); } diff --git a/src/widgets/styles/qgtkstyle.cpp b/src/widgets/styles/qgtkstyle.cpp index 0b67277a63..a585755ddd 100644 --- a/src/widgets/styles/qgtkstyle.cpp +++ b/src/widgets/styles/qgtkstyle.cpp @@ -3633,6 +3633,13 @@ QRect QGtkStyle::subControlRect(ComplexControl control, const QStyleOptionComple QFont font = widget->font(); font.setBold(true); fontMetrics = QFontMetrics(font); + } else if (QStyleHelper::isInstanceOf(groupBox->styleObject, QAccessible::Grouping)) { + QVariant var = groupBox->styleObject->property("font"); + if (var.isValid() && var.canConvert<QFont>()) { + QFont font = var.value<QFont>(); + font.setBold(true); + fontMetrics = QFontMetrics(font); + } } QSize textRect = fontMetrics.boundingRect(groupBox->text).size() + QSize(4, 4); diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp index 965278265a..e413b3b87a 100644 --- a/src/widgets/widgets/qabstractbutton.cpp +++ b/src/widgets/widgets/qabstractbutton.cpp @@ -1293,8 +1293,10 @@ void QAbstractButton::focusInEvent(QFocusEvent *e) void QAbstractButton::focusOutEvent(QFocusEvent *e) { Q_D(QAbstractButton); - if (e->reason() != Qt::PopupFocusReason) + if (e->reason() != Qt::PopupFocusReason && d->down) { d->down = false; + d->emitReleased(); + } QWidget::focusOutEvent(e); } @@ -1304,8 +1306,10 @@ void QAbstractButton::changeEvent(QEvent *e) Q_D(QAbstractButton); switch (e->type()) { case QEvent::EnabledChange: - if (!isEnabled()) - setDown(false); + if (!isEnabled() && d->down) { + d->down = false; + d->emitReleased(); + } break; default: d->sizeHint = QSize(); diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp index 41fd418459..2e1caedde7 100644 --- a/src/widgets/widgets/qabstractscrollarea.cpp +++ b/src/widgets/widgets/qabstractscrollarea.cpp @@ -444,19 +444,11 @@ void QAbstractScrollAreaPrivate::layoutChildren() const QPoint cornerPoint(controlsRect.bottomRight() + QPoint(1, 1) - cornerOffset); // Some styles paints the corner if both scorllbars are showing and there is - // no corner widget. Also, on the Mac we paint if there is a native - // (transparent) sizegrip in the area where a corner widget would be. - if ((needv && needh && hasCornerWidget == false && hscrollOverlap == 0 && vscrollOverlap == 0) - || ((needv || needh) -#ifdef Q_DEAD_CODE_FROM_QT4_MAC - && hasMacSizeGrip -#endif - ) - ) { + // no corner widget. + if (needv && needh && !hasCornerWidget && hscrollOverlap == 0 && vscrollOverlap == 0) cornerPaintingRect = QStyle::visualRect(opt.direction, opt.rect, QRect(cornerPoint, extSize)); - } else { + else cornerPaintingRect = QRect(); - } #ifdef Q_DEAD_CODE_FROM_QT4_MAC if (hasMacReverseSizeGrip) diff --git a/src/widgets/widgets/qprogressbar.cpp b/src/widgets/widgets/qprogressbar.cpp index 6bc44f06fe..8034a0237a 100644 --- a/src/widgets/widgets/qprogressbar.cpp +++ b/src/widgets/widgets/qprogressbar.cpp @@ -347,6 +347,8 @@ int QProgressBar::value() const If the current value falls outside the new range, the progress bar is reset with reset(). + The QProgressBar can be set to undetermined state by using setRange(0, 0). + \sa minimum, maximum */ void QProgressBar::setRange(int minimum, int maximum) diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index 1194f695f1..943d5c28a4 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -514,7 +514,7 @@ public: QDomAttrPrivate* createAttributeNS(const QString& nsURI, const QString& qName); QDomEntityReferencePrivate* createEntityReference(const QString& name); - QDomNodePrivate* importNode(const QDomNodePrivate* importedNode, bool deep); + QDomNodePrivate* importNode(QDomNodePrivate* importedNode, bool deep); // Reimplemented from QDomNodePrivate QDomNodePrivate* cloneNode(bool deep = true) Q_DECL_OVERRIDE; @@ -6371,7 +6371,7 @@ QDomEntityReferencePrivate* QDomDocumentPrivate::createEntityReference(const QSt return e; } -QDomNodePrivate* QDomDocumentPrivate::importNode(const QDomNodePrivate *importedNode, bool deep) +QDomNodePrivate* QDomDocumentPrivate::importNode(QDomNodePrivate *importedNode, bool deep) { QDomNodePrivate *node = 0; switch (importedNode->nodeType()) { diff --git a/tests/auto/cmake/test_add_resource_options/CMakeLists.txt b/tests/auto/cmake/test_add_resource_options/CMakeLists.txt index a358094546..5fcae59dfe 100644 --- a/tests/auto/cmake/test_add_resource_options/CMakeLists.txt +++ b/tests/auto/cmake/test_add_resource_options/CMakeLists.txt @@ -20,6 +20,9 @@ qt5_wrap_cpp(moc_files myobject.h) # in the add_executable call. qt5_add_resources(rcc_files "test_macro_options.qrc" OPTIONS -binary) +# Test if OPTIONS can handle a quoted parameter. CMake would fail immediately! +qt5_add_resources(rcc_files_quoted_option "test_macro_options.qrc" OPTIONS -root "/") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") add_executable(myobject myobject.cpp ${moc_files} ${rcc_files}) diff --git a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp index 3d0b102b1c..8ffe4d8dfe 100644 --- a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp +++ b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp @@ -385,14 +385,14 @@ void tst_QtConcurrentRun::recursive() count.store(0); QThreadPool::globalInstance()->setMaxThreadCount(i); recursiveRun(levels); - QCOMPARE(count.load(), (int)pow(2.0, levels) - 1); + QCOMPARE(count.load(), (int)std::pow(2.0, levels) - 1); } for (int i = 0; i < QThread::idealThreadCount(); ++i) { count.store(0); QThreadPool::globalInstance()->setMaxThreadCount(i); recursiveResult(levels); - QCOMPARE(count.load(), (int)pow(2.0, levels) - 1); + QCOMPARE(count.load(), (int)std::pow(2.0, levels) - 1); } } diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 2015629a59..7579c6713d 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. -** Copyright (C) 2012 Intel Corporation. +** Copyright (C) 2015 Intel Corporation. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -1248,6 +1248,10 @@ void tst_QUrl::fromLocalFile_data() << QString::fromLatin1("/a%25.txt"); QTest::newRow("data10") << QString::fromLatin1("/%80.txt") << QString::fromLatin1("file:///%2580.txt") << QString::fromLatin1("/%80.txt"); + QTest::newRow("data11") << QString::fromLatin1("./a.txt") << QString::fromLatin1("file:a.txt") << QString::fromLatin1("a.txt"); + QTest::newRow("data12") << QString::fromLatin1("././a.txt") << QString::fromLatin1("file:a.txt") << QString::fromLatin1("a.txt"); + QTest::newRow("data13") << QString::fromLatin1("b/../a.txt") << QString::fromLatin1("file:a.txt") << QString::fromLatin1("a.txt"); + QTest::newRow("data14") << QString::fromLatin1("/b/../a.txt") << QString::fromLatin1("file:///a.txt") << QString::fromLatin1("/a.txt"); } void tst_QUrl::fromLocalFile() @@ -2012,6 +2016,11 @@ void tst_QUrl::isValid() QVERIFY(url.toString().isEmpty()); QVERIFY(url.errorString().contains("':' before any '/'")); } + + { + QUrl url("file://./localfile.html"); + QVERIFY(!url.isValid()); + } } void tst_QUrl::schemeValidator_data() diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 449ae947cf..6da8f55e61 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -48,6 +48,7 @@ #include <limits.h> #include <float.h> +#include <cmath> #include <QLinkedList> #include <QRegularExpression> @@ -3373,10 +3374,10 @@ void tst_QVariant::numericalConvert() switch (v.userType()) { case QVariant::Double: - QCOMPARE(v.toString() , QString::number(num, 'g', DBL_MANT_DIG * log10(2.) + 2)); + QCOMPARE(v.toString() , QString::number(num, 'g', DBL_MANT_DIG * std::log10(2.) + 2)); break; case QMetaType::Float: - QCOMPARE(v.toString() , QString::number(float(num), 'g', FLT_MANT_DIG * log10(2.) + 2)); + QCOMPARE(v.toString() , QString::number(float(num), 'g', FLT_MANT_DIG * std::log10(2.) + 2)); break; } } diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index 446e56e936..4ab79909e3 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -611,13 +611,11 @@ void tst_QDateTime::setMSecsSinceEpoch() dt2.setTimeZone(europe); dt2.setMSecsSinceEpoch(msecs); QCOMPARE(dt2.date(), european.date()); -#ifdef Q_OS_MAC - // NSTimeZone doesn't apply DST to high values - if (msecs < (Q_INT64_C(123456) << 32)) -#else - // Linux and Win are OK except when they overflow - if (msecs != std::numeric_limits<qint64>::max()) -#endif + + // don't compare the time if the date is too early or too late: prior + // to 1916, timezones in Europe were not standardised and some OS APIs + // have hard limits. Let's restrict it to the 32-bit Unix range + if (dt2.date().year() >= 1970 && dt2.date().year() <= 2037) QCOMPARE(dt2.time(), european.time()); QCOMPARE(dt2.timeSpec(), Qt::TimeZone); QCOMPARE(dt2.timeZone(), europe); @@ -2634,10 +2632,10 @@ void tst_QDateTime::daylightTransitions() const QVERIFY(test.isValid()); QCOMPARE(test.date(), QDate(2012, 10, 28)); QCOMPARE(test.time(), QTime(2, 0, 0)); -#if !defined(Q_OS_MAC) && !defined(Q_OS_QNX) - // Linux mktime bug uses last calculation +#ifdef Q_OS_WIN + // Windows uses SecondOccurrence QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue); -#endif // Q_OS_MAC +#endif // Q_OS_WIN QCOMPARE(test.toMSecsSinceEpoch(), standard2012 - msecsOneHour); // Add year to get to after tran FirstOccurrence @@ -2676,10 +2674,10 @@ void tst_QDateTime::daylightTransitions() const QVERIFY(test.isValid()); QCOMPARE(test.date(), QDate(2012, 10, 28)); QCOMPARE(test.time(), QTime(2, 0, 0)); -#if !defined(Q_OS_MAC) && !defined(Q_OS_QNX) - // Linux mktime bug uses last calculation +#ifdef Q_OS_WIN + // Windows uses SecondOccurrence QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue); -#endif // Q_OS_MAC +#endif // Q_OS_WIN QCOMPARE(test.toMSecsSinceEpoch(), standard2012 - msecsOneHour); // Add month to get to after tran FirstOccurrence @@ -2718,10 +2716,10 @@ void tst_QDateTime::daylightTransitions() const QVERIFY(test.isValid()); QCOMPARE(test.date(), QDate(2012, 10, 28)); QCOMPARE(test.time(), QTime(2, 0, 0)); -#if !defined(Q_OS_MAC) && !defined(Q_OS_QNX) - // Linux mktime bug uses last calculation +#ifdef Q_OS_WIN + // Windows uses SecondOccurrence QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue); -#endif // Q_OS_MAC +#endif // Q_OS_WIN QCOMPARE(test.toMSecsSinceEpoch(), standard2012 - msecsOneHour); // Add day to get to after tran FirstOccurrence diff --git a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp index b33982695b..8726f77e58 100644 --- a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp +++ b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp @@ -753,7 +753,7 @@ void tst_QEasingCurve::testCbrtDouble() if (f != 0.0) t = t * (t_cubic + d + d) / f; - double expected = pow(d, 1.0/3.0); + double expected = std::pow(d, 1.0/3.0); const qreal error = qAbs(expected - t); @@ -779,7 +779,7 @@ void tst_QEasingCurve::testCbrtFloat() if (fac != 0.0f) t = t * (t_cubic + f + f) / fac; - float expected = pow(f, float(1.0/3.0)); + float expected = std::pow(f, float(1.0/3.0)); const qreal error = qAbs(expected - t); diff --git a/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp b/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp index 436cedcca7..ff58c9b181 100644 --- a/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp +++ b/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp @@ -275,12 +275,12 @@ void tst_QPointF::division() { { QPointF p(1e-14, 1e-14); - p = p / sqrt(dot(p, p)); + p = p / std::sqrt(dot(p, p)); QCOMPARE(dot(p, p), qreal(1.0)); } { QPointF p(1e-14, 1e-14); - p /= sqrt(dot(p, p)); + p /= std::sqrt(dot(p, p)); QCOMPARE(dot(p, p), qreal(1.0)); } } diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 8cd9610542..d2f7a6ee50 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -2033,6 +2033,8 @@ void tst_QString::simplified_data() QTest::newRow("chars apart posttab") << "a \tb" << "a b"; QTest::newRow("chars apart pretab") << "a\t b" << "a b"; QTest::newRow("many words") << " just some random\ttext here" << "just some random text here"; + QTest::newRow("newlines") << "a\nb\nc" << "a b c"; + QTest::newRow("newlines-trailing") << "a\nb\nc\n" << "a b c"; } void tst_QString::simplified() diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index 8ce0e3942e..d361aa12a6 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -1464,7 +1464,7 @@ void tst_QWindow::initialSize() QSize defaultSize(0,0); { Window w; - w.show(); + w.showNormal(); QTRY_VERIFY(w.width() > 0); QTRY_VERIFY(w.height() > 0); defaultSize = QSize(w.width(), w.height()); @@ -1472,7 +1472,7 @@ void tst_QWindow::initialSize() { Window w; w.setWidth(m_testWindowSize.width()); - w.show(); + w.showNormal(); #if defined(Q_OS_BLACKBERRY) // "window" is the "root" window and will always be shown fullscreen // so we only expect one resize event QTRY_COMPARE(w.width(), qGuiApp->primaryScreen()->availableGeometry().width()); @@ -1485,7 +1485,7 @@ void tst_QWindow::initialSize() Window w; const QSize testSize(m_testWindowSize.width(), 42); w.resize(testSize); - w.show(); + w.showNormal(); #if defined(Q_OS_BLACKBERRY) // "window" is the "root" window and will always be shown fullscreen // so we only expect one resize event diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 159bb6a041..f6167262a9 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -111,6 +111,7 @@ private slots: void drawLine_task190634(); void drawLine_task229459(); void drawLine_task234891(); + void drawLineEndPoints(); void drawRect_data() { fillData(); } void drawRect(); @@ -1036,6 +1037,50 @@ void tst_QPainter::drawLine_task216948() QCOMPARE(img.pixel(0, i), QColor(Qt::black).rgba()); } +void tst_QPainter::drawLineEndPoints() +{ + QImage img(256, 256, QImage::Format_ARGB32_Premultiplied); + img.fill(0x0); + + QPainter p; + for (int x = 0; x < img.width(); ++x) { + QRgb color = qRgb(x, 0, 0); + p.begin(&img); + p.setPen(QPen(color)); + p.drawLine(x, 0, 255 - x, 255); + p.end(); + QCOMPARE(img.pixel(x, 0), color); + QCOMPARE(img.pixel(255 - x, 255), color); + } + for (int y = 0; y < img.height(); ++y) { + QRgb color = qRgb(0, y, 0); + p.begin(&img); + p.setPen(QPen(color)); + p.drawLine(0, y, 255, 255 - y); + p.end(); + QCOMPARE(img.pixel(0, y), color); + QCOMPARE(img.pixel(255, 255 - y), color); + } + for (int x = 0; x < img.width(); ++x) { + QRgb color = qRgb(x, 0, x); + p.begin(&img); + p.setPen(QPen(color)); + p.drawLine(x, 255, 255 - x, 0); + p.end(); + QCOMPARE(img.pixel(x, 255), color); + QCOMPARE(img.pixel(255 - x, 0), color); + } + for (int y = 0; y < img.height(); ++y) { + QRgb color = qRgb(0, y, y); + p.begin(&img); + p.setPen(QPen(color)); + p.drawLine(255, y, 0, 255 - y); + p.end(); + QCOMPARE(img.pixel(255, y), color); + QCOMPARE(img.pixel(0, 255 - y), color); + } +} + void tst_QPainter::drawRect() { QFETCH(QRect, rect); diff --git a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp index 4252561001..0a073f5c84 100644 --- a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp +++ b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp @@ -895,12 +895,6 @@ void tst_QPainterPath::operators() QCOMPARE(test, expected); } -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif -#define ANGLE(t) ((t) * 2 * M_PI / 360.0) - - static inline bool pathFuzzyCompare(double p1, double p2) { return qAbs(p1 - p2) < 0.001; @@ -931,7 +925,7 @@ void tst_QPainterPath::testArcMoveTo() qreal y_radius = rect.height() / 2.0; QPointF shouldBe = rect.center() - + QPointF(x_radius * cos(ANGLE(angle)), -y_radius * sin(ANGLE(angle))); + + QPointF(x_radius * qCos(qDegreesToRadians(angle)), -y_radius * qSin(qDegreesToRadians(angle))); qreal iw = 1 / rect.width(); qreal ih = 1 / rect.height(); diff --git a/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp b/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp index a1017eea3b..c4c4789b7a 100644 --- a/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp +++ b/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp @@ -152,125 +152,125 @@ void tst_QWMatrix::mapping_data() // rotations float deg = 0.; - QTest::newRow( "rot 0 a" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ), - sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 0 a" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), + std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 0, 0, 30, 40 ) << QPolygon ( QRect( 0, 0, 30, 40 ) ); deg = 0.00001f; - QTest::newRow( "rot 0 b" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ), - sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 0 b" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), + std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 0, 0, 30, 40 ) << QPolygon ( QRect( 0, 0, 30, 40 ) ); deg = 0.; - QTest::newRow( "rot 0 c" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ), - sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 0 c" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), + std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 10, 20, 30, 40 ) << QPolygon ( QRect( 10, 20, 30, 40 ) ); deg = 0.00001f; - QTest::newRow( "rot 0 d" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ), - sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 0 d" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), + std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 10, 20, 30, 40 ) << QPolygon ( QRect( 10, 20, 30, 40 ) ); #if 0 // rotations deg = 90.; - QTest::newRow( "rotscale 90 a" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ), - 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 90 a" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), + 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( 0, -299, 400, 300 ) ); deg = 90.00001; - QTest::newRow( "rotscale 90 b" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ), - 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 90 b" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), + 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( 0, -299, 400, 300 ) ); deg = 90.; - QTest::newRow( "rotscale 90 c" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ), - 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 90 c" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), + 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 200, -399, 400, 300 ) ); deg = 90.00001; - QTest::newRow( "rotscale 90 d" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ), - 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 90 d" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), + 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 200, -399, 400, 300 ) ); deg = 180.; - QTest::newRow( "rotscale 180 a" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ), - 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 180 a" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), + 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -299, -399, 300, 400 ) ); deg = 180.000001; - QTest::newRow( "rotscale 180 b" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ), - 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 180 b" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), + 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -299, -399, 300, 400 ) ); deg = 180.; - QTest::newRow( "rotscale 180 c" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ), - 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 180 c" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), + 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -399, -599, 300, 400 ) ); deg = 180.000001; - QTest::newRow( "rotscale 180 d" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ), - 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 180 d" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), + 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -399, -599, 300, 400 ) ); deg = 270.; - QTest::newRow( "rotscale 270 a" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ), - 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 270 a" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), + 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -399, 00, 400, 300 ) ); deg = 270.0000001; - QTest::newRow( "rotscale 270 b" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ), - 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 270 b" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), + 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -399, 00, 400, 300 ) ); deg = 270.; - QTest::newRow( "rotscale 270 c" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ), - 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 270 c" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), + 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -599, 100, 400, 300 ) ); deg = 270.000001; - QTest::newRow( "rotscale 270 d" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ), - 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 270 d" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), + 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -599, 100, 400, 300 ) ); // rotations that are not multiples of 90 degrees. mapRect returns the bounding rect here. deg = 45; - QTest::newRow( "rot 45 a" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ), - sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 45 a" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), + std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 0, 0, 10, 10 ) << QPolygon( QRect( 0, -7, 14, 14 ) ); - QTest::newRow( "rot 45 b" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ), - sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 45 b" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), + std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 21, -14, 49, 49 ) ); - QTest::newRow( "rot 45 c" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ), - 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 45 c" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), + 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 0, 0, 10, 10 ) << QPolygon( QRect( 0, -70, 141, 141 ) ); - QTest::newRow( "rot 45 d" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ), - 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 45 d" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), + 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 212, -141, 495, 495 ) ); deg = -45; - QTest::newRow( "rot -45 a" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ), - sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot -45 a" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), + std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 0, 0, 10, 10 ) << QPolygon( QRect( -7, 0, 14, 14 ) ); - QTest::newRow( "rot -45 b" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ), - sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot -45 b" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), + std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -35, 21, 49, 49 ) ); - QTest::newRow( "rot -45 c" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ), - 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot -45 c" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), + 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 0, 0, 10, 10 ) << QPolygon( QRect( -70, 0, 141, 141 ) ); - QTest::newRow( "rot -45 d" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ), - 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot -45 d" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), + 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -353, 212, 495, 495 ) ); #endif diff --git a/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp b/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp index 6f1a73b054..804f86b479 100644 --- a/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp +++ b/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp @@ -864,11 +864,12 @@ void tst_QTcpServer::serverAddress_data() QTest::newRow("AnyIPv4") << QHostAddress(QHostAddress::AnyIPv4) << QHostAddress(QHostAddress::AnyIPv4); if (QtNetworkSettings::hasIPv6()) QTest::newRow("AnyIPv6") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv6); - foreach (const QHostAddress& addr, QNetworkInterface::allAddresses()) { - if (addr.isInSubnet(QHostAddress::parseSubnet("fe80::/10")) - || addr.isInSubnet(QHostAddress::parseSubnet("169.254/16"))) - continue; //cannot bind on link local addresses - QTest::newRow(qPrintable(addr.toString())) << addr << addr; + foreach (const QNetworkInterface &iface, QNetworkInterface::allInterfaces()) { + if ((iface.flags() & QNetworkInterface::IsUp) == 0) + continue; + foreach (const QNetworkAddressEntry &entry, iface.addressEntries()) { + QTest::newRow(qPrintable(entry.ip().toString())) << entry.ip() << entry.ip(); + } } } diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 4bd330b04f..6e04cd9d0e 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -1233,6 +1233,8 @@ void tst_QUdpSocket::setMulticastInterface_data() QTest::addColumn<QHostAddress>("address"); QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces(); foreach (const QNetworkInterface &iface, interfaces) { + if ((iface.flags() & QNetworkInterface::IsUp) == 0) + continue; foreach (const QNetworkAddressEntry &entry, iface.addressEntries()) { QTest::newRow(QString("%1:%2").arg(iface.name()).arg(entry.ip().toString()).toLatin1()) << iface diff --git a/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp b/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp index 1833af7af5..4fd8b99acf 100644 --- a/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp +++ b/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp @@ -76,11 +76,7 @@ private slots: void sizeHint_data(); void sizeHint(); void taskQTBUG_20191_shortcutWithKeypadModifer(); -/* - void state(); - void group(); - void stateChanged(); -*/ + void emitReleasedAfterChange(); protected slots: void resetCounters(); @@ -419,19 +415,6 @@ void tst_QPushButton::clicked() QCOMPARE( release_count, (uint)10 ); } -/* -void tst_QPushButton::group() -{ -} - -void tst_QPushButton::state() -{ -} - -void tst_QPushButton::stateChanged() -{ -} -*/ QPushButton *pb = 0; void tst_QPushButton::helperSlotDelete() { @@ -681,5 +664,36 @@ void tst_QPushButton::taskQTBUG_20191_shortcutWithKeypadModifer() QCOMPARE(spy2.count(), 1); } +void tst_QPushButton::emitReleasedAfterChange() +{ + QPushButton *button1 = new QPushButton("A"); + QPushButton *button2 = new QPushButton("B"); + QVBoxLayout *layout = new QVBoxLayout(); + layout->addWidget(button1); + layout->addWidget(button2); + QDialog dialog; + dialog.setLayout(layout); + dialog.show(); + QTest::qWaitForWindowExposed(&dialog); + QApplication::setActiveWindow(&dialog); + button1->setFocus(); + + QSignalSpy spy(button1, SIGNAL(released())); + QTest::mousePress(button1, Qt::LeftButton); + QVERIFY(button1->isDown()); + QTest::keyClick(&dialog, Qt::Key_Tab); + QVERIFY(!button1->isDown()); + QCOMPARE(spy.count(), 1); + spy.clear(); + + QCOMPARE(spy.count(), 0); + button1->setFocus(); + QTest::mousePress(button1, Qt::LeftButton); + QVERIFY(button1->isDown()); + button1->setEnabled(false); + QVERIFY(!button1->isDown()); + QCOMPARE(spy.count(), 1); +} + QTEST_MAIN(tst_QPushButton) #include "tst_qpushbutton.moc" diff --git a/tests/benchmarks/corelib/tools/qregexp/main.cpp b/tests/benchmarks/corelib/tools/qregexp/main.cpp index 88d3b3fa96..aa31b037fe 100644 --- a/tests/benchmarks/corelib/tools/qregexp/main.cpp +++ b/tests/benchmarks/corelib/tools/qregexp/main.cpp @@ -75,17 +75,13 @@ private slots: void rangeReplace2(); void matchReplace2(); -#ifdef HAVE_JSC void simpleFindJSC(); void rangeReplaceJSC(); void matchReplaceJSC(); -#endif -#ifdef HAVE_BOOST void simpleFindBoost(); void rangeReplaceBoost(); void matchReplaceBoost(); -#endif /* those apply an (incorrect) regexp on entire source (this main.cpp). JSC appears to handle this @@ -95,14 +91,10 @@ private slots: void horribleReplace1(); void horribleReplace2(); void horribleWrongReplace2(); -#ifdef HAVE_JSC void horribleWrongReplaceJSC(); void horribleReplaceJSC(); -#endif -#ifdef HAVE_BOOST void horribleWrongReplaceBoost(); void horribleReplaceBoost(); -#endif private: QString str1; QString str2; @@ -451,9 +443,9 @@ void tst_qregexp::horribleReplace2() } QCOMPARE(r, QString("1.2.3")); } -#ifdef HAVE_JSC void tst_qregexp::simpleFindJSC() { +#ifdef HAVE_JSC int numr; const char * errmsg=" "; QString rxs("happy"); @@ -467,10 +459,14 @@ void tst_qregexp::simpleFindJSC() jsRegExpFree(rx); QCOMPARE(numr, 1); QCOMPARE(offsetVector[0], 11); +#else + QSKIP("JSC is not enabled for this platform"); +#endif } void tst_qregexp::rangeReplaceJSC() { +#ifdef HAVE_JSC QScriptValue r; QScriptEngine engine; engine.globalObject().setProperty("s", str1); @@ -480,10 +476,14 @@ void tst_qregexp::rangeReplaceJSC() r = replaceFunc.call(QScriptValue()); } QCOMPARE(r.toString(), QString("W- -r- -ll h-ppy monk-ys")); +#else + QSKIP("JSC is not enabled for this platform"); +#endif } void tst_qregexp::matchReplaceJSC() { +#ifdef HAVE_JSC QScriptValue r; QScriptEngine engine; engine.globalObject().setProperty("s", str1); @@ -493,10 +493,14 @@ void tst_qregexp::matchReplaceJSC() r = replaceFunc.call(QScriptValue()); } QCOMPARE(r.toString(), QString("eaeaae")); +#else + QSKIP("JSC is not enabled for this platform"); +#endif } void tst_qregexp::horribleWrongReplaceJSC() { +#ifdef HAVE_JSC QScriptValue r; QScriptEngine engine; engine.globalObject().setProperty("s", str2); @@ -506,10 +510,14 @@ void tst_qregexp::horribleWrongReplaceJSC() r = replaceFunc.call(QScriptValue()); } QCOMPARE(r.toString(), str2); +#else + QSKIP("JSC is not enabled for this platform"); +#endif } void tst_qregexp::horribleReplaceJSC() { +#ifdef HAVE_JSC QScriptValue r; QScriptEngine engine; // the m flag doesn't actually work here; dunno @@ -520,11 +528,14 @@ void tst_qregexp::horribleReplaceJSC() r = replaceFunc.call(QScriptValue()); } QCOMPARE(r.toString(), QString("1.2.3")); -} +#else + QSKIP("JSC is not enabled for this platform"); #endif +} +void tst_qregexp::simpleFindBoost() +{ #ifdef HAVE_BOOST -void tst_qregexp::simpleFindBoost(){ int roff; boost::regex rx ("happy", boost::regex_constants::perl); std::string s = str1.toStdString(); @@ -538,10 +549,15 @@ void tst_qregexp::simpleFindBoost(){ roff = (what[0].first)-start; } QCOMPARE(roff, 11); +#else + QSKIP("Boost is not enabled for this platform"); +#endif + } void tst_qregexp::rangeReplaceBoost() { +#ifdef HAVE_BOOST boost::regex pattern ("[a-f]", boost::regex_constants::perl); std::string s = str1.toStdString(); std::string r; @@ -549,10 +565,14 @@ void tst_qregexp::rangeReplaceBoost() r = boost::regex_replace (s, pattern, "-"); } QCOMPARE(r, std::string("W- -r- -ll h-ppy monk-ys")); +#else + QSKIP("Boost is not enabled for this platform"); +#endif } void tst_qregexp::matchReplaceBoost() { +#ifdef HAVE_BOOST boost::regex pattern ("[^a-f]*([a-f]+)[^a-f]*",boost::regex_constants::perl); std::string s = str1.toStdString(); std::string r; @@ -560,10 +580,14 @@ void tst_qregexp::matchReplaceBoost() r = boost::regex_replace (s, pattern, "$1"); } QCOMPARE(r, std::string("eaeaae")); +#else + QSKIP("Boost is not enabled for this platform"); +#endif } void tst_qregexp::horribleWrongReplaceBoost() { +#ifdef HAVE_BOOST boost::regex pattern (".*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+)\".*", boost::regex_constants::perl); std::string s = str2.toStdString(); std::string r; @@ -571,10 +595,14 @@ void tst_qregexp::horribleWrongReplaceBoost() r = boost::regex_replace (s, pattern, "$1.$2.$3"); } QCOMPARE(r, s); +#else + QSKIP("Boost is not enabled for this platform"); +#endif } void tst_qregexp::horribleReplaceBoost() { +#ifdef HAVE_BOOST boost::regex pattern (".*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+).*", boost::regex_constants::perl); std::string s = str2.toStdString(); std::string r; @@ -582,8 +610,10 @@ void tst_qregexp::horribleReplaceBoost() r = boost::regex_replace (s, pattern, "$1.$2.$3"); } QCOMPARE(r, std::string("1.2.3")); +#else + QSKIP("Boost is not enabled for this platform"); +#endif } -#endif //HAVE_BOOST QTEST_MAIN(tst_qregexp) diff --git a/tests/benchmarks/corelib/tools/qregexp/qregexp.pro b/tests/benchmarks/corelib/tools/qregexp/qregexp.pro index d194d2b698..8b35ecffed 100644 --- a/tests/benchmarks/corelib/tools/qregexp/qregexp.pro +++ b/tests/benchmarks/corelib/tools/qregexp/qregexp.pro @@ -11,9 +11,11 @@ qtHaveModule(script):!pcre { QT += script } -exists($$[QT_SYSROOT]/usr/include/boost/regex.hpp) { -DEFINES+=HAVE_BOOST -LIBS+=-lboost_regex +!qnx { + exists($$[QT_SYSROOT]/usr/include/boost/regex.hpp) { + DEFINES += HAVE_BOOST + LIBS += -lboost_regex + } } DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/manual/cocoa/popups/main.cpp b/tests/manual/cocoa/popups/main.cpp new file mode 100644 index 0000000000..46249d6772 --- /dev/null +++ b/tests/manual/cocoa/popups/main.cpp @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <QtWidgets> + +class Window : public QWidget +{ + Q_OBJECT + +public: + Window(); + +public slots: + void triggered(QAction*); + void clean(); + void showPoppWindow(); + +private: + QLabel *explanation; + QToolButton *toolButton; + QMenu *menu; + QLineEdit *echo; + QComboBox *comboBox; + QPushButton *pushButton; +}; + +Window::Window() +{ + QGroupBox* group = new QGroupBox(tr("test the popup")); + + explanation = new QLabel( + "This test is used to verify that popup windows will be closed " + "as expected. This includes when clicking outside the popup or moving the " + "parent window. Tested popups include context menus, combo box popups, tooltips " + "and QWindow with Qt::Popup set." + ); + explanation->setWordWrap(true); + explanation->setToolTip("I'm a tool tip!"); + + menu = new QMenu(group); + menu->addAction(tr("line one")); + menu->addAction(tr("line two")); + menu->addAction(tr("line three")); + menu->addAction(tr("line four")); + menu->addAction(tr("line five")); + + QMenu *subMenu1 = new QMenu(); + subMenu1->addAction("1"); + subMenu1->addAction("2"); + subMenu1->addAction("3"); + menu->addMenu(subMenu1); + + QMenu *subMenu2 = new QMenu(); + subMenu2->addAction("2 1"); + subMenu2->addAction("2 2"); + subMenu2->addAction("2 3"); + menu->addMenu(subMenu2); + + toolButton = new QToolButton(group); + toolButton->setMenu(menu); + toolButton->setPopupMode( QToolButton::MenuButtonPopup ); + toolButton->setText("select me"); + + echo = new QLineEdit(group); + echo->setPlaceholderText("not triggered"); + + connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(triggered(QAction*))); + connect(menu, SIGNAL(aboutToShow()), this, SLOT(clean())); + + comboBox = new QComboBox(); + comboBox->addItem("Item 1"); + comboBox->addItem("Item 2"); + comboBox->addItem("Item 3"); + + pushButton = new QPushButton("Show popup window"); + connect(pushButton, SIGNAL(clicked()), this, SLOT(showPoppWindow())); + + QVBoxLayout* layout = new QVBoxLayout; + layout->addWidget(explanation); + layout->addWidget(toolButton); + layout->addWidget(echo); + layout->addWidget(comboBox); + layout->addWidget(pushButton); + + group ->setLayout(layout); + setLayout(layout); + setWindowTitle(tr("Popup Window Testing")); +} + +void Window::clean() +{ + echo->setText(""); +} + +void Window::showPoppWindow() +{ + QWindow *window = new QWindow(); + window->setTransientParent(this->windowHandle()); + window->setPosition(this->pos()); + window->setWidth(100); + window->setHeight(100); + window->setFlags(Qt::Window | Qt::Popup); + window->show(); +} + +void Window::triggered(QAction* act) +{ + if (!act) + return; + echo->setText(act->text()); +} + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + Window window; + window.show(); + return app.exec(); +} + +#include "main.moc" diff --git a/tests/manual/cocoa/popups/popups.pro b/tests/manual/cocoa/popups/popups.pro new file mode 100644 index 0000000000..d0a3d44171 --- /dev/null +++ b/tests/manual/cocoa/popups/popups.pro @@ -0,0 +1,4 @@ +QT += widgets + +SOURCES = main.cpp +CONFIG -= app_bundle diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index ed4eb7e09a..4f78660db4 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -182,6 +182,7 @@ Configure::Configure(int& argc, char** argv) dictionary[ "QT_ICONV" ] = "auto"; dictionary[ "QT_EVDEV" ] = "auto"; dictionary[ "QT_MTDEV" ] = "auto"; + dictionary[ "QT_TSLIB" ] = "auto"; dictionary[ "QT_INOTIFY" ] = "auto"; dictionary[ "QT_EVENTFD" ] = "auto"; dictionary[ "QT_CUPS" ] = "auto"; @@ -245,6 +246,8 @@ Configure::Configure(int& argc, char** argv) dictionary[ "SHARED" ] = "yes"; + dictionary[ "STATIC_RUNTIME" ] = "no"; + dictionary[ "ZLIB" ] = "auto"; dictionary[ "PCRE" ] = "auto"; @@ -464,6 +467,8 @@ void Configure::parseCmdLine() dictionary[ "SHARED" ] = "yes"; else if (configCmdLine.at(i) == "-static") dictionary[ "SHARED" ] = "no"; + else if (configCmdLine.at(i) == "-static-runtime") + dictionary[ "STATIC_RUNTIME" ] = "yes"; else if (configCmdLine.at(i) == "-developer-build") dictionary[ "BUILDDEV" ] = "yes"; else if (configCmdLine.at(i) == "-opensource") { @@ -1269,12 +1274,6 @@ void Configure::parseCmdLine() dictionary["QT_INOTIFY"] = "no"; } - else if (configCmdLine.at(i) == "-neon") { - dictionary["NEON"] = "yes"; - } else if (configCmdLine.at(i) == "-no-neon") { - dictionary["NEON"] = "no"; - } - else if (configCmdLine.at(i) == "-largefile") { dictionary["LARGE_FILE"] = "yes"; } @@ -1781,6 +1780,8 @@ bool Configure::displayHelp() desc("SHARED", "yes", "-shared", "Create and use shared Qt libraries."); desc("SHARED", "no", "-static", "Create and use static Qt libraries.\n"); + desc("STATIC_RUNTIME", "no", "-static-runtime","Statically link the C/C++ runtime library.\n"); + desc("LTCG", "yes", "-ltcg", "Use Link Time Code Generation. (Release builds only)"); desc("LTCG", "no", "-no-ltcg", "Do not use Link Time Code Generation.\n"); @@ -1846,9 +1847,6 @@ bool Configure::displayHelp() desc("NIS", "no", "-no-nis", "Do not compile NIS support."); desc("NIS", "yes", "-nis", "Compile NIS support.\n"); - desc("NEON", "yes", "-neon", "Enable the use of NEON instructions."); - desc("NEON", "no", "-no-neon", "Do not enable the use of NEON instructions.\n"); - desc("QT_ICONV", "disable", "-no-iconv", "Do not enable support for iconv(3)."); desc("QT_ICONV", "yes", "-iconv", "Enable support for iconv(3)."); desc("QT_ICONV", "yes", "-sun-iconv", "Enable support for iconv(3) using sun-iconv."); @@ -2277,6 +2275,8 @@ bool Configure::checkAvailability(const QString &part) available = tryCompileProject("unix/evdev"); } else if (part == "MTDEV") { available = tryCompileProject("unix/mtdev"); + } else if (part == "TSLIB") { + available = tryCompileProject("unix/tslib"); } else if (part == "INOTIFY") { available = tryCompileProject("unix/inotify"); } else if (part == "QT_EVENTFD") { @@ -2447,6 +2447,10 @@ void Configure::autoDetection() if (dictionary["QT_MTDEV"] == "auto") dictionary["QT_MTDEV"] = checkAvailability("MTDEV") ? "yes" : "no"; + // Detection of tslib support + if (dictionary["QT_TSLIB"] == "auto") + dictionary["QT_TSLIB"] = checkAvailability("TSLIB") ? "yes" : "no"; + // Detection of inotify if (dictionary["QT_INOTIFY"] == "auto") dictionary["QT_INOTIFY"] = checkAvailability("INOTIFY") ? "yes" : "no"; @@ -2508,6 +2512,11 @@ bool Configure::verifyConfiguration() dictionary["C++11"] = "auto"; } + if (dictionary["STATIC_RUNTIME"] == "yes" && dictionary["SHARED"] == "yes") { + cout << "ERROR: -static-runtime requires -static" << endl << endl; + dictionary[ "DONE" ] = "error"; + } + if (dictionary["SEPARATE_DEBUG_INFO"] == "yes") { if (dictionary[ "SHARED" ] == "no") { cout << "ERROR: -separate-debug-info is incompatible with -static" << endl << endl; @@ -2653,6 +2662,9 @@ void Configure::generateOutputVars() else qtConfig += "shared"; + if (dictionary[ "STATIC_RUNTIME" ] == "yes") + qtConfig += "static_runtime"; + if (dictionary[ "GUI" ] == "no") { qtConfig += "no-gui"; dictionary [ "WIDGETS" ] = "no"; @@ -2900,6 +2912,9 @@ void Configure::generateOutputVars() if (dictionary["QT_MTDEV"] == "yes") qtConfig += "mtdev"; + if (dictionary[ "QT_TSLIB" ] == "yes") + qtConfig += "tslib"; + if (dictionary["QT_INOTIFY"] == "yes") qtConfig += "inotify"; @@ -3371,6 +3386,8 @@ void Configure::generateQConfigPri() configStream << dictionary[ "BUILD" ]; configStream << (dictionary[ "SHARED" ] == "no" ? " static" : " shared"); + if (dictionary["STATIC_RUNTIME"] == "yes") + configStream << " static_runtime"; if (dictionary[ "LTCG" ] == "yes") configStream << " ltcg"; if (dictionary[ "RTTI" ] == "yes") @@ -3604,6 +3621,7 @@ void Configure::generateConfigfiles() if (dictionary["QT_ICONV"] == "no") qconfigList += "QT_NO_ICONV"; if (dictionary["QT_EVDEV"] == "no") qconfigList += "QT_NO_EVDEV"; if (dictionary["QT_MTDEV"] == "no") qconfigList += "QT_NO_MTDEV"; + if (dictionary["QT_TSLIB"] == "no") qconfigList += "QT_NO_TSLIB"; if (dictionary["QT_GLIB"] == "no") qconfigList += "QT_NO_GLIB"; if (dictionary["QT_INOTIFY"] == "no") qconfigList += "QT_NO_INOTIFY"; if (dictionary["QT_EVENTFD"] == "no") qconfigList += "QT_NO_EVENTFD"; |