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
This commit is contained in:
Simon Hausmann 2015-03-16 10:31:07 +01:00
commit 198606f6db
259 changed files with 4384 additions and 2628 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -68,12 +68,8 @@
in the explicit \c editor member variable. in the explicit \c editor member variable.
We then create a QTreeWidget as a toplevel widget and configure the various We then create a QTreeWidget as a toplevel widget and configure the various
properties to give it the look of a popup widget. properties to give it the look of a popup widget. The widget is populated
with the results by Google Suggest API request.
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.
Furthermore, we install the GSuggestCompletion instance as an event filter Furthermore, we install the GSuggestCompletion instance as an event filter
on the QTreeWidget, and connect the \c itemClicked() signal with the \c on the QTreeWidget, and connect the \c itemClicked() signal with the \c
@ -110,8 +106,8 @@
\snippet googlesuggest/googlesuggest.cpp 4 \snippet googlesuggest/googlesuggest.cpp 4
The \c showCompletion() function populates the QTreeWidget with the results The \c showCompletion() function populates the QTreeWidget with the results
returned from the query. It takes two QStringLists, one with the suggested returned from the query. It takes a QStringList of the suggested search
search terms and the other with the corresponding number of hits. terms.
\snippet googlesuggest/googlesuggest.cpp 5 \snippet googlesuggest/googlesuggest.cpp 5

View File

@ -38,7 +38,6 @@
** **
****************************************************************************/ ****************************************************************************/
//! [1] //! [1]
#include "googlesuggest.h" #include "googlesuggest.h"
@ -54,7 +53,7 @@ GSuggestCompletion::GSuggestCompletion(QLineEdit *parent): QObject(parent), edit
popup->setFocusProxy(parent); popup->setFocusProxy(parent);
popup->setMouseTracking(true); popup->setMouseTracking(true);
popup->setColumnCount(2); popup->setColumnCount(1);
popup->setUniformRowHeights(true); popup->setUniformRowHeights(true);
popup->setRootIsDecorated(false); popup->setRootIsDecorated(false);
popup->setEditTriggers(QTreeWidget::NoEditTriggers); popup->setEditTriggers(QTreeWidget::NoEditTriggers);
@ -137,10 +136,10 @@ bool GSuggestCompletion::eventFilter(QObject *obj, QEvent *ev)
//! [4] //! [4]
//! [5] //! [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; return;
const QPalette &pal = editor->palette(); const QPalette &pal = editor->palette();
@ -152,19 +151,12 @@ void GSuggestCompletion::showCompletion(const QStringList &choices, const QStrin
QTreeWidgetItem * item; QTreeWidgetItem * item;
item = new QTreeWidgetItem(popup); item = new QTreeWidgetItem(popup);
item->setText(0, choices[i]); item->setText(0, choices[i]);
item->setText(1, hits[i]); item->setTextColor(0, color);
item->setTextAlignment(1, Qt::AlignRight);
item->setTextColor(1, color);
} }
popup->setCurrentItem(popup->topLevelItem(0)); popup->setCurrentItem(popup->topLevelItem(0));
popup->resizeColumnToContents(0); popup->resizeColumnToContents(0);
popup->resizeColumnToContents(1);
popup->adjustSize();
popup->setUpdatesEnabled(true); 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->move(editor->mapToGlobal(QPoint(0, editor->height())));
popup->setFocus(); popup->setFocus();
popup->show(); popup->show();
@ -207,7 +199,6 @@ void GSuggestCompletion::handleNetworkData(QNetworkReply *networkReply)
QUrl url = networkReply->url(); QUrl url = networkReply->url();
if (!networkReply->error()) { if (!networkReply->error()) {
QStringList choices; QStringList choices;
QStringList hits;
QByteArray response(networkReply->readAll()); QByteArray response(networkReply->readAll());
QXmlStreamReader xml(response); QXmlStreamReader xml(response);
@ -218,17 +209,11 @@ void GSuggestCompletion::handleNetworkData(QNetworkReply *networkReply)
QStringRef str = xml.attributes().value("data"); QStringRef str = xml.attributes().value("data");
choices << str.toString(); 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(); networkReply->deleteLater();
} }
//! [9] //! [9]

View File

@ -61,7 +61,7 @@ public:
GSuggestCompletion(QLineEdit *parent = 0); GSuggestCompletion(QLineEdit *parent = 0);
~GSuggestCompletion(); ~GSuggestCompletion();
bool eventFilter(QObject *obj, QEvent *ev) Q_DECL_OVERRIDE; bool eventFilter(QObject *obj, QEvent *ev) Q_DECL_OVERRIDE;
void showCompletion(const QStringList &choices, const QStringList &hits); void showCompletion(const QStringList &choices);
public slots: public slots:

View File

@ -10,6 +10,7 @@ include(unix.conf)
QMAKE_CC = qcc -Vgcc_ntoarmv7le QMAKE_CC = qcc -Vgcc_ntoarmv7le
QMAKE_CXX = qcc -Vgcc_ntoarmv7le QMAKE_CXX = qcc -Vgcc_ntoarmv7le
QNX_CPUDIR = armle-v7 QNX_CPUDIR = armle-v7
QMAKE_CFLAGS += -mfpu=neon
include(qcc-base-qnx.conf) include(qcc-base-qnx.conf)

View File

@ -33,7 +33,6 @@ QMAKE_CFLAGS_SSE4_1 += -msse4.1
QMAKE_CFLAGS_SSE4_2 += -msse4.2 QMAKE_CFLAGS_SSE4_2 += -msse4.2
QMAKE_CFLAGS_AVX += -mavx QMAKE_CFLAGS_AVX += -mavx
QMAKE_CFLAGS_AVX2 += -mavx2 QMAKE_CFLAGS_AVX2 += -mavx2
QMAKE_CFLAGS_NEON += -mfpu=neon
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS -lang-c++ QMAKE_CXXFLAGS += $$QMAKE_CFLAGS -lang-c++
QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS

View File

@ -80,7 +80,7 @@ defineTest(qtAddModule) {
unset(LINKAGE) unset(LINKAGE)
mac:contains(MODULE_CONFIG, lib_bundle) { mac:contains(MODULE_CONFIG, lib_bundle) {
FRAMEWORK_INCLUDE = $${MODULE_LIBS}/$${MODULE_NAME}.framework/Headers FRAMEWORK_INCLUDE = $${MODULE_LIBS}/$${MODULE_NAME}.framework/Headers
!qt_no_framework_direct_includes:exists($$FRAMEWORK_INCLUDE) { !qt_no_framework_direct_includes {
INCLUDEPATH *= $$FRAMEWORK_INCLUDE INCLUDEPATH *= $$FRAMEWORK_INCLUDE
} }
contains(MODULE_CONFIG, internal_module): \ contains(MODULE_CONFIG, internal_module): \

View File

@ -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
}

View File

@ -52,25 +52,18 @@ insignificant_test:check.commands = -$${check.commands}
QMAKE_EXTRA_TARGETS *= check QMAKE_EXTRA_TARGETS *= check
!debug_and_release|build_pass { isEmpty(BUILDS)|build_pass {
check.depends = first check.depends = first
} else { } else {
# For exclusive builds, only run the test once.
check.CONFIG = recursive check.CONFIG = recursive
# In debug and release mode, only run the test once. check.target = check_all
# Run debug if that is the preferred config, release otherwise. check.recurse_target = check
debug_and_release { check.commands =
check.target = dummy_check
check.recurse_target = check check_first.depends = $$eval($$first(BUILDS).target)-check
CONFIG(debug, debug|release) { check_first.target = check
real_check.depends = debug-check QMAKE_EXTRA_TARGETS += check_first
real_check.target = check
QMAKE_EXTRA_TARGETS += real_check
} else {
real_check.depends = release-check
real_check.target = check
QMAKE_EXTRA_TARGETS += real_check
}
}
} }
!no_testcase_installs:!contains(INSTALLS, target) { !no_testcase_installs:!contains(INSTALLS, target) {

View File

@ -9,19 +9,21 @@ have_target:!static:!isEmpty(QMAKE_OBJCOPY) {
debug_info_keep = --only-keep-debug debug_info_keep = --only-keep-debug
debug_info_strip = --strip-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\" load(resolve_target)
QMAKE_INSTALL_SEPARATE_DEBUG_INFO = test -z \"$(DESTDIR)\" || cd \"$(DESTDIR)\" ; $(INSTALL_FILE) `basename $(TARGET)`.$$debug_info_suffix $(INSTALL_ROOT)/\$\$target_path/ 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 !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 silent:QMAKE_POST_LINK = @echo creating $@.$$debug_info_suffix && $$QMAKE_POST_LINK
isEmpty(DESTDIR) { target.targets += $$QMAKE_TARGET_DEBUG_INFO
target.targets += "`basename $(TARGET)`.$$debug_info_suffix" QMAKE_DISTCLEAN += $$QMAKE_TARGET_DEBUG_INFO
QMAKE_DISTCLEAN += "`basename $(TARGET)`.$$debug_info_suffix"
} else {
target.targets += "$(DESTDIR)/`basename $(TARGET)`.$$debug_info_suffix"
QMAKE_DISTCLEAN += "$(DESTDIR)/`basename $(TARGET)`.$$debug_info_suffix"
}
} }

View File

@ -71,7 +71,9 @@
exists($$UUID_CACHE) { exists($$UUID_CACHE) {
include($$UUID_CACHE) include($$UUID_CACHE)
} else { } 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.") write_file($$UUID_CACHE, WINRT_UUID)|error("Unable to write the UUID cache; aborting.")
eval($$WINRT_UUID) eval($$WINRT_UUID)
} }

View File

@ -41,7 +41,6 @@ equals(TEMPLATE, app) {
RESOURCES = RESOURCES =
INSTALLS = INSTALLS =
QMAKE_EXTRA_COMPILERS = QMAKE_EXTRA_COMPILERS =
QMAKE_EXTRA_TARGETS =
!build_pass { !build_pass {
CONFIG += debug_and_release CONFIG += debug_and_release
@ -97,7 +96,24 @@ equals(TEMPLATE, app) {
target = $${sdk}-$${cfg}$${action_target_suffix} 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 QMAKE_EXTRA_TARGETS += $$target
$${action_target}.depends += $$target $${action_target}.depends += $$target

View File

@ -558,6 +558,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("name", "Qt Qmake") << ";\n" << "\t\t\t" << writeSettings("name", "Qt Qmake") << ";\n"
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\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("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n"
<< "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n"
<< "\t\t};\n"; << "\t\t};\n";
} }
@ -795,6 +796,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("name", "Qt Preprocessors") << ";\n" << "\t\t\t" << writeSettings("name", "Qt Preprocessors") << ";\n"
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\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("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n"
<< "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n"
<< "\t\t};\n"; << "\t\t};\n";
} }
@ -1070,6 +1072,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("name", "Qt Postlink") << ";\n" << "\t\t\t" << writeSettings("name", "Qt Postlink") << ";\n"
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n" << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n"
<< "\t\t\t" << writeSettings("shellScript", project->values("QMAKE_POST_LINK")) << ";\n" << "\t\t\t" << writeSettings("shellScript", project->values("QMAKE_POST_LINK")) << ";\n"
<< "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n"
<< "\t\t};\n"; << "\t\t};\n";
} }
@ -1088,6 +1091,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n" << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\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("shellScript", fixForOutput("cp -r $BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME " + IoUtils::shellQuoteUnix(destDir))) << ";\n"
<< "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n"
<< "\t\t};\n"; << "\t\t};\n";
} }
bool copyBundleResources = project->isActiveConfig("app_bundle") && project->first("TEMPLATE") == "app"; bool copyBundleResources = project->isActiveConfig("app_bundle") && project->first("TEMPLATE") == "app";

View File

@ -388,6 +388,7 @@ void NmakeMakefileGenerator::init()
ProString version = project->first("TARGET_VERSION_EXT"); ProString version = project->first("TARGET_VERSION_EXT");
if(project->isActiveConfig("shared")) { if(project->isActiveConfig("shared")) {
project->values("QMAKE_CLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".exp"); 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")) { if (project->isActiveConfig("debug_info")) {
QString pdbfile = project->first("DESTDIR") + project->first("TARGET") + version + ".pdb"; QString pdbfile = project->first("DESTDIR") + project->first("TARGET") + version + ".pdb";

View File

@ -38,7 +38,7 @@
#ifndef _GNU_SOURCE #ifndef _GNU_SOURCE
# define _GNU_SOURCE # define _GNU_SOURCE
# define _POSIX_C_SOURCE 200809L # define _POSIX_C_SOURCE 200809L
# define _XOPEN_SOURCE 500 # define _XOPEN_SOURCE 700
#endif #endif
#include "forkfd.h" #include "forkfd.h"
@ -436,6 +436,7 @@ static int create_pipe(int filedes[], int flags)
return ret; return ret;
} }
#ifndef FORKFD_NO_FORKFD
/** /**
* @brief forkfd returns a file descriptor representing a child process * @brief forkfd returns a file descriptor representing a child process
* @return a file descriptor, or -1 in case of failure * @return a file descriptor, or -1 in case of failure
@ -590,8 +591,9 @@ err_free:
freeInfo(header, info); freeInfo(header, info);
return -1; 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, 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[]) posix_spawnattr_t *attrp, char *const argv[], char *const envp[])
{ {
@ -652,4 +654,4 @@ err_free:
out: out:
return -1; return -1;
} }
#endif // _POSIX_SPAWN #endif // _POSIX_SPAWN && !FORKFD_NO_SPAWNFD

View File

@ -9,15 +9,15 @@ Changes:
- rename from strtoxx_l to qt_strtoxx (merging the two functions) - rename from strtoxx_l to qt_strtoxx (merging the two functions)
- remove __restrict - remove __restrict
- remove the locale_t parameter and use ascii_isspace instead of isspace_l - 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/strtoll.c | 27 ++++-----------------------
src/3rdparty/freebsd/strtoull.c | 27 +++++---------------------- src/3rdparty/freebsd/strtoull.c | 27 ++++-----------------------
2 files changed, 10 insertions(+), 44 deletions(-) 2 files changed, 8 insertions(+), 46 deletions(-)
diff --git a/src/3rdparty/freebsd/strtoll.c b/src/3rdparty/freebsd/strtoll.c 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 --- a/src/3rdparty/freebsd/strtoll.c
+++ b/src/3rdparty/freebsd/strtoll.c +++ b/src/3rdparty/freebsd/strtoll.c
@@ -32,18 +32,6 @@ @@ -32,18 +32,6 @@
@ -39,7 +39,7 @@ index 16a8196..0ded267 100644
/* /*
* Convert a string to a long long integer. * 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. * alphabets and digits are each contiguous.
*/ */
long long long long
@ -72,7 +72,8 @@ index 16a8196..0ded267 100644
- acc = -acc; - acc = -acc;
+ acc = (unsigned long long) -(long long)acc; + acc = (unsigned long long) -(long long)acc;
if (endptr != NULL) 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); return (acc);
} }
-long long -long long
@ -81,7 +82,7 @@ index 16a8196..0ded267 100644
- return strtoll_l(nptr, endptr, base, __get_locale()); - return strtoll_l(nptr, endptr, base, __get_locale());
-} -}
diff --git a/src/3rdparty/freebsd/strtoull.c b/src/3rdparty/freebsd/strtoull.c 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 --- a/src/3rdparty/freebsd/strtoull.c
+++ b/src/3rdparty/freebsd/strtoull.c +++ b/src/3rdparty/freebsd/strtoull.c
@@ -32,18 +32,6 @@ @@ -32,18 +32,6 @@
@ -103,7 +104,7 @@ index dc40e0e..cb04adb 100644
/* /*
* Convert a string to an unsigned long long integer. * 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. * alphabets and digits are each contiguous.
*/ */
unsigned long long unsigned long long
@ -136,7 +137,8 @@ index dc40e0e..cb04adb 100644
- acc = -acc; - acc = -acc;
+ acc = (unsigned long long) -(long long)acc; + acc = (unsigned long long) -(long long)acc;
if (endptr != NULL) 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); return (acc);
} }
-unsigned long long -unsigned long long
@ -145,5 +147,5 @@ index dc40e0e..cb04adb 100644
- return strtoull_l(nptr, endptr, base, __get_locale()); - return strtoull_l(nptr, endptr, base, __get_locale());
-} -}
-- --
1.8.4.5 2.1.4

View File

@ -129,6 +129,6 @@ noconv:
} else if (neg) } else if (neg)
acc = (unsigned long long) -(long long)acc; acc = (unsigned long long) -(long long)acc;
if (endptr != NULL) if (endptr != NULL)
*endptr = (char *)(any ? s - 1 : nptr); *endptr = const_cast<char *>(any ? s - 1 : nptr);
return (acc); return (acc);
} }

View File

@ -107,6 +107,6 @@ noconv:
} else if (neg) } else if (neg)
acc = (unsigned long long) -(long long)acc; acc = (unsigned long long) -(long long)acc;
if (endptr != NULL) if (endptr != NULL)
*endptr = (char *)(any ? s - 1 : nptr); *endptr = const_cast<char *>(any ? s - 1 : nptr);
return (acc); return (acc);
} }

67
src/3rdparty/freetype.pri vendored Normal file
View File

@ -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/*

View File

@ -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 Overview of changes leading to 0.9.38
Friday, January 23, 2015 Friday, January 23, 2015
===================================== =====================================

View File

@ -454,7 +454,7 @@ hb_buffer_t::reverse_range (unsigned int start,
info[j] = t; info[j] = t;
} }
if (pos) { if (have_positions) {
for (i = start, j = end - 1; i < j; i++, j--) { for (i = start, j = end - 1; i < j; i++, j--) {
hb_glyph_position_t t; hb_glyph_position_t t;

View File

@ -53,7 +53,8 @@ struct TTCHeader;
typedef struct TableRecord typedef struct TableRecord
{ {
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this)); return TRACE_RETURN (c->check_struct (this));
} }
@ -102,7 +103,8 @@ typedef struct OffsetTable
} }
public: public:
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables)); 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 unsigned int get_face_count (void) const { return table.len; }
inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; } 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); TRACE_SANITIZE (this);
return TRACE_RETURN (table.sanitize (c, 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); TRACE_SANITIZE (this);
if (unlikely (!u.header.version.sanitize (c))) return TRACE_RETURN (false); if (unlikely (!u.header.version.sanitize (c))) return TRACE_RETURN (false);
switch (u.header.version.major) { 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); TRACE_SANITIZE (this);
if (unlikely (!u.tag.sanitize (c))) return TRACE_RETURN (false); if (unlikely (!u.tag.sanitize (c))) return TRACE_RETURN (false);
switch (u.tag) { switch (u.tag) {

View File

@ -179,10 +179,13 @@ struct hb_sanitize_context_t
inline const char *get_name (void) { return "SANITIZE"; } inline const char *get_name (void) { return "SANITIZE"; }
static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE; static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE;
typedef bool return_t; 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> template <typename T>
inline return_t dispatch (const T &obj) { return obj.sanitize (this); } inline return_t dispatch (const T &obj) { return obj.sanitize (this); }
static return_t default_return_value (void) { return true; } 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) inline void init (hb_blob_t *b)
{ {
@ -270,9 +273,9 @@ struct hb_sanitize_context_t
} }
template <typename Type, typename ValueType> 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)) { if (this->may_edit (obj, obj->static_size)) {
obj->set (v); const_cast<Type *> (obj)->set (v);
return true; return true;
} }
return false; return false;
@ -546,12 +549,6 @@ struct BEInt<Type, 2>
return (v[0] << 8) return (v[0] << 8)
+ (v[1] ); + (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]; private: uint8_t v[2];
}; };
template <typename Type> template <typename Type>
@ -570,13 +567,6 @@ struct BEInt<Type, 3>
+ (v[1] << 8) + (v[1] << 8)
+ (v[2] ); + (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]; private: uint8_t v[3];
}; };
template <typename Type> template <typename Type>
@ -597,14 +587,6 @@ struct BEInt<Type, 4>
+ (v[2] << 8) + (v[2] << 8)
+ (v[3] ); + (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]; private: uint8_t v[4];
}; };
@ -614,12 +596,19 @@ struct IntType
{ {
inline void set (Type i) { v.set (i); } inline void set (Type i) { v.set (i); }
inline operator Type(void) const { return v; } 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 (Type) v == (Type) 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 !(*this == o); }
static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); } 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
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) { 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); TRACE_SANITIZE (this);
return TRACE_RETURN (likely (c->check_struct (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. */ * 1904. The value is represented as a signed 64-bit integer. */
struct LONGDATETIME struct LONGDATETIME
{ {
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (likely (c->check_struct (this))); return TRACE_RETURN (likely (c->check_struct (this)));
} }
@ -670,7 +660,10 @@ struct Tag : ULONG
DEFINE_NULL_DATA (Tag, " "); DEFINE_NULL_DATA (Tag, " ");
/* Glyph index number, same as uint16 (length = 16 bits) */ /* 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 */ /* Script/language-system/feature index */
struct Index : USHORT { struct Index : USHORT {
@ -719,7 +712,8 @@ struct FixedVersion
{ {
inline uint32_t to_int (void) const { return (major << 16) + minor; } 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this)); return TRACE_RETURN (c->check_struct (this));
} }
@ -747,33 +741,35 @@ struct OffsetTo : Offset<OffsetType>
return StructAtOffset<Type> (base, offset); 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> (); Type *t = c->start_embed<Type> ();
this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */ this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
return *t; 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); TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
unsigned int offset = *this; unsigned int offset = *this;
if (unlikely (!offset)) return TRACE_RETURN (true); 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)); return TRACE_RETURN (likely (obj.sanitize (c)) || neuter (c));
} }
template <typename T> 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); TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
unsigned int offset = *this; unsigned int offset = *this;
if (unlikely (!offset)) return TRACE_RETURN (true); 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)); return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c));
} }
/* Set the offset to Null */ /* 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); return c->try_set (this, 0);
} }
DEFINE_SIZE_STATIC (sizeof(OffsetType)); DEFINE_SIZE_STATIC (sizeof(OffsetType));
@ -838,7 +834,8 @@ struct ArrayOf
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
@ -853,7 +850,8 @@ struct ArrayOf
return TRACE_RETURN (true); 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); TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
unsigned int count = len; unsigned int count = len;
@ -863,7 +861,8 @@ struct ArrayOf
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
template <typename T> 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); TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
unsigned int count = len; unsigned int count = len;
@ -884,7 +883,8 @@ struct ArrayOf
} }
private: private:
inline bool sanitize_shallow (hb_sanitize_context_t *c) { inline bool sanitize_shallow (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::static_size, len)); 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]; 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); TRACE_SANITIZE (this);
return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this)); return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this));
} }
template <typename T> 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); TRACE_SANITIZE (this);
return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this, user_data)); return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this, user_data));
} }
@ -949,12 +951,14 @@ struct HeadlessArrayOf
return TRACE_RETURN (true); 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) return c->check_struct (this)
&& c->check_array (this, Type::static_size, len); && 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); TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);

View File

@ -51,7 +51,8 @@ struct CmapSubtableFormat0
return true; return true;
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this)); return TRACE_RETURN (c->check_struct (this));
} }
@ -125,7 +126,7 @@ struct CmapSubtableFormat4
return true; return true;
} }
inline bool sanitize (hb_sanitize_context_t *c) inline bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this))) if (unlikely (!c->check_struct (this)))
@ -183,7 +184,8 @@ struct CmapSubtableLongGroup
return 0; return 0;
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this)); return TRACE_RETURN (c->check_struct (this));
} }
@ -210,7 +212,8 @@ struct CmapSubtableTrimmed
return true; return true;
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && glyphIdArray.sanitize (c)); return TRACE_RETURN (c->check_struct (this) && glyphIdArray.sanitize (c));
} }
@ -242,7 +245,8 @@ struct CmapSubtableLongSegmented
return true; return true;
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && groups.sanitize (c)); return TRACE_RETURN (c->check_struct (this) && groups.sanitize (c));
} }
@ -288,7 +292,8 @@ struct UnicodeValueRange
return 0; return 0;
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this)); return TRACE_RETURN (c->check_struct (this));
} }
@ -309,7 +314,8 @@ struct UVSMapping
return unicodeValue.cmp (codepoint); return unicodeValue.cmp (codepoint);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this)); return TRACE_RETURN (c->check_struct (this));
} }
@ -348,7 +354,8 @@ struct VariationSelectorRecord
return varSelector.cmp (variation_selector); 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && return TRACE_RETURN (c->check_struct (this) &&
defaultUVS.sanitize (c, base) && defaultUVS.sanitize (c, base) &&
@ -373,7 +380,8 @@ struct CmapSubtableFormat14
return record[record.bsearch(variation_selector)].get_glyph (codepoint, glyph, this); 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && return TRACE_RETURN (c->check_struct (this) &&
record.sanitize (c, 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); TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false); if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) { switch (u.format) {
@ -461,7 +470,8 @@ struct EncodingRecord
return 0; 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && return TRACE_RETURN (c->check_struct (this) &&
subtable.sanitize (c, base)); subtable.sanitize (c, base));
@ -496,7 +506,8 @@ struct cmap
return &(this+encodingRecord[result].subtable); 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && return TRACE_RETURN (c->check_struct (this) &&
likely (version == 0) && likely (version == 0) &&

View File

@ -45,13 +45,15 @@ struct head
{ {
static const hb_tag_t tableTag = HB_OT_TAG_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; unsigned int upem = unitsPerEm;
/* If no valid head table found, assume 1000, which matches typical Type1 usage. */ /* If no valid head table found, assume 1000, which matches typical Type1 usage. */
return 16 <= upem && upem <= 16384 ? upem : 1000; 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1)); return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1));
} }

View File

@ -49,7 +49,8 @@ struct _hea
static const hb_tag_t hheaTag = HB_OT_TAG_hhea; static const hb_tag_t hheaTag = HB_OT_TAG_hhea;
static const hb_tag_t vheaTag = HB_OT_TAG_vhea; 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1)); return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1));
} }

View File

@ -57,7 +57,8 @@ struct _mtx
static const hb_tag_t hmtxTag = HB_OT_TAG_hmtx; static const hb_tag_t hmtxTag = HB_OT_TAG_hmtx;
static const hb_tag_t vmtxTag = HB_OT_TAG_vmtx; 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); TRACE_SANITIZE (this);
/* We don't check for anything specific here. The users of the /* We don't check for anything specific here. The users of the
* struct do all the hard work... */ * struct do all the hard work... */

View File

@ -37,6 +37,12 @@
namespace OT { 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 NOT_COVERED ((unsigned int) -1)
#define MAX_NESTING_LEVEL 8 #define MAX_NESTING_LEVEL 8
#define MAX_CONTEXT_LENGTH 64 #define MAX_CONTEXT_LENGTH 64
@ -63,9 +69,10 @@ struct Record
struct sanitize_closure_t { struct sanitize_closure_t {
hb_tag_t tag; 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); TRACE_SANITIZE (this);
const sanitize_closure_t closure = {tag, base}; const sanitize_closure_t closure = {tag, base};
return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base, &closure)); 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 inline const Type& operator [] (unsigned int i) const
{ return this+RecordArrayOf<Type>::operator [](i).offset; } { 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); TRACE_SANITIZE (this);
return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this)); return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this));
} }
@ -134,7 +142,8 @@ struct RangeRecord
return g < start ? -1 : g <= end ? 0 : +1 ; 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this)); return TRACE_RETURN (c->check_struct (this));
} }
@ -199,7 +208,8 @@ struct LangSys
} }
inline bool sanitize (hb_sanitize_context_t *c, 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c)); 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 const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
inline bool sanitize (hb_sanitize_context_t *c, 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); TRACE_SANITIZE (this);
return TRACE_RETURN (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, 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 */ /* http://www.microsoft.com/typography/otspec/features_pt.htm#size */
struct FeatureParamsSize struct FeatureParamsSize
{ {
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); 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 */ /* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */
struct FeatureParamsStylisticSet struct FeatureParamsStylisticSet
{ {
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
/* Right now minorVersion is at zero. Which means, any table supports /* Right now minorVersion is at zero. Which means, any table supports
* the uiNameID field. */ * the uiNameID field. */
@ -404,7 +417,8 @@ struct FeatureParamsStylisticSet
/* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */ /* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */
struct FeatureParamsCharacterVariants struct FeatureParamsCharacterVariants
{ {
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && return TRACE_RETURN (c->check_struct (this) &&
characters.sanitize (c)); characters.sanitize (c));
@ -444,7 +458,8 @@ struct FeatureParamsCharacterVariants
struct FeatureParams 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); TRACE_SANITIZE (this);
if (tag == HB_TAG ('s','i','z','e')) if (tag == HB_TAG ('s','i','z','e'))
return TRACE_RETURN (u.size.sanitize (c)); return TRACE_RETURN (u.size.sanitize (c));
@ -486,7 +501,8 @@ struct Feature
{ return this+featureParams; } { return this+featureParams; }
inline bool sanitize (hb_sanitize_context_t *c, 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); TRACE_SANITIZE (this);
if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c))))
return TRACE_RETURN (false); return TRACE_RETURN (false);
@ -561,6 +577,17 @@ struct Lookup
{ {
inline unsigned int get_subtable_count (void) const { return subTable.len; } 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; } inline unsigned int get_type (void) const { return lookupType; }
/* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and
@ -577,6 +604,20 @@ struct Lookup
return flag; 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, inline bool serialize (hb_serialize_context_t *c,
unsigned int lookup_type, unsigned int lookup_type,
uint32_t lookup_props, uint32_t lookup_props,
@ -595,18 +636,20 @@ struct Lookup
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
/* Real sanitize of the subtables is done by GSUB/GPOS/... */ /* Real sanitize of the subtables is done by GSUB/GPOS/... */
if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN (false); if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN (false);
if (lookupFlag & LookupFlag::UseMarkFilteringSet) if (lookupFlag & LookupFlag::UseMarkFilteringSet)
{ {
USHORT &markFilteringSet = StructAfter<USHORT> (subTable); const USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false); if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false);
} }
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
private:
USHORT lookupType; /* Different enumerations for GSUB and GPOS */ USHORT lookupType; /* Different enumerations for GSUB and GPOS */
USHORT lookupFlag; /* Lookup qualifiers */ USHORT lookupFlag; /* Lookup qualifiers */
ArrayOf<Offset<> > ArrayOf<Offset<> >
@ -651,7 +694,8 @@ struct CoverageFormat1
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (glyphArray.sanitize (c)); return TRACE_RETURN (glyphArray.sanitize (c));
} }
@ -737,7 +781,8 @@ struct CoverageFormat2
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (rangeRecord.sanitize (c)); 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); TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false); if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) { switch (u.format) {
@ -938,12 +984,14 @@ struct ClassDefFormat1
private: private:
inline unsigned int get_class (hb_codepoint_t glyph_id) const inline unsigned int get_class (hb_codepoint_t glyph_id) const
{ {
if (unlikely ((unsigned int) (glyph_id - startGlyph) < classValue.len)) unsigned int i = (unsigned int) (glyph_id - startGlyph);
return classValue[glyph_id - startGlyph]; if (unlikely (i < classValue.len))
return classValue[i];
return 0; return 0;
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && classValue.sanitize (c)); 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 inline unsigned int get_class (hb_codepoint_t glyph_id) const
{ {
int i = rangeRecord.bsearch (glyph_id); int i = rangeRecord.bsearch (glyph_id);
if (i != -1) if (unlikely (i != -1))
return rangeRecord[i].value; return rangeRecord[i].value;
return 0; return 0;
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (rangeRecord.sanitize (c)); 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); TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false); if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) { switch (u.format) {
@ -1148,7 +1198,8 @@ struct Device
return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f))); 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->get_size ())); return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->get_size ()));
} }

View File

@ -71,7 +71,8 @@ struct AttachList
return points.len; return points.len;
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && attachPoint.sanitize (c, 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); 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this)); return TRACE_RETURN (c->check_struct (this));
} }
@ -127,7 +129,8 @@ struct CaretValueFormat2
return 0; return 0;
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (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); 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && deviceTable.sanitize (c, 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); TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false); if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) { switch (u.format) {
@ -219,7 +224,8 @@ struct LigGlyph
return carets.len; return carets.len;
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (carets.sanitize (c, 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); 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); TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && ligGlyph.sanitize (c, 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 inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
{ return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; } { 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); TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, 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); TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false); if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) { switch (u.format) {
@ -364,7 +373,8 @@ struct GDEF
inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const 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); } { 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); TRACE_SANITIZE (this);
return TRACE_RETURN (version.sanitize (c) && return TRACE_RETURN (version.sanitize (c) &&
likely (version.major == 1) && likely (version.major == 1) &&

View File

@ -146,7 +146,8 @@ struct ValueFormat : USHORT
} }
private: 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; unsigned int format = *this;
if (format & xPlacement) values++; if (format & xPlacement) values++;
@ -177,12 +178,14 @@ struct ValueFormat : USHORT
return (format & devices) != 0; 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values))); 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); TRACE_SANITIZE (this);
unsigned int len = get_len (); unsigned int len = get_len ();
@ -200,7 +203,8 @@ struct ValueFormat : USHORT
} }
/* Just sanitize referenced Device tables. Doesn't check the values themselves. */ /* 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); TRACE_SANITIZE (this);
if (!has_device ()) return TRACE_RETURN (true); if (!has_device ()) return TRACE_RETURN (true);
@ -225,7 +229,8 @@ struct AnchorFormat1
*y = font->em_scale_y (yCoordinate); *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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this)); return TRACE_RETURN (c->check_struct (this));
} }
@ -254,7 +259,8 @@ struct AnchorFormat2
*y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate); *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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this)); return TRACE_RETURN (c->check_struct (this));
} }
@ -282,7 +288,8 @@ struct AnchorFormat3
*y += (this+yDeviceTable).get_x_delta (font); *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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, 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); TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false); if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) { switch (u.format) {
@ -349,7 +357,8 @@ struct AnchorMatrix
return this+matrixZ[row * cols + col]; 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); TRACE_SANITIZE (this);
if (!c->check_struct (this)) return TRACE_RETURN (false); if (!c->check_struct (this)) return TRACE_RETURN (false);
if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) 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; 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base)); 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); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this)); return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this));
} }
@ -457,9 +468,12 @@ struct SinglePosFormat1
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); 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: protected:
@ -506,9 +520,12 @@ struct SinglePosFormat2
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); 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: protected:
@ -531,6 +548,7 @@ struct SinglePos
inline typename context_t::return_t dispatch (context_t *c) const inline typename context_t::return_t dispatch (context_t *c) const
{ {
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
switch (u.format) { switch (u.format) {
case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 1: return TRACE_RETURN (c->dispatch (u.format1));
case 2: return TRACE_RETURN (c->dispatch (u.format2)); 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: protected:
union { union {
USHORT format; /* Format identifier */ USHORT format; /* Format identifier */
@ -636,19 +644,20 @@ struct PairSet
} }
struct sanitize_closure_t { struct sanitize_closure_t {
void *base; const void *base;
ValueFormat *valueFormats; const ValueFormat *valueFormats;
unsigned int len1; /* valueFormats[0].get_len() */ unsigned int len1; /* valueFormats[0].get_len() */
unsigned int stride; /* 1 + len1 + len2 */ 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); TRACE_SANITIZE (this);
if (!(c->check_struct (this) if (!(c->check_struct (this)
&& c->check_array (arrayZ, USHORT::static_size * closure->stride, len))) return TRACE_RETURN (false); && c->check_array (arrayZ, USHORT::static_size * closure->stride, len))) return TRACE_RETURN (false);
unsigned int count = len; 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) 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)); && 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); TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer; 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); unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 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); if (!skippy_iter.next ()) return TRACE_RETURN (false);
return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx)); 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); TRACE_SANITIZE (this);
unsigned int len1 = valueFormat1.get_len (); unsigned int len1 = valueFormat1.get_len ();
@ -752,12 +761,11 @@ struct PairPosFormat2
{ {
TRACE_APPLY (this); TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer; 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); unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 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); if (!skippy_iter.next ()) return TRACE_RETURN (false);
unsigned int len1 = valueFormat1.get_len (); unsigned int len1 = valueFormat1.get_len ();
@ -781,7 +789,8 @@ struct PairPosFormat2
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (!(c->check_struct (this) if (!(c->check_struct (this)
&& coverage.sanitize (c, this) && coverage.sanitize (c, this)
@ -834,6 +843,7 @@ struct PairPos
inline typename context_t::return_t dispatch (context_t *c) const inline typename context_t::return_t dispatch (context_t *c) const
{ {
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
switch (u.format) { switch (u.format) {
case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 1: return TRACE_RETURN (c->dispatch (u.format1));
case 2: return TRACE_RETURN (c->dispatch (u.format2)); 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: protected:
union { union {
USHORT format; /* Format identifier */ USHORT format; /* Format identifier */
@ -864,7 +864,8 @@ struct EntryExitRecord
{ {
friend struct CursivePosFormat1; 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); TRACE_SANITIZE (this);
return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base)); return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
} }
@ -903,12 +904,11 @@ struct CursivePosFormat1
/* We don't handle mark glyphs here. */ /* We don't handle mark glyphs here. */
if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return TRACE_RETURN (false); 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)]; const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)];
if (!this_record.exitAnchor) return TRACE_RETURN (false); 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); if (!skippy_iter.next ()) return TRACE_RETURN (false);
const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)]; 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); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, 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 inline typename context_t::return_t dispatch (context_t *c) const
{ {
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
switch (u.format) { switch (u.format) {
case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 1: return TRACE_RETURN (c->dispatch (u.format1));
default:return TRACE_RETURN (c->default_return_value ()); 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: protected:
union { union {
USHORT format; /* Format identifier */ USHORT format; /* Format identifier */
@ -1051,7 +1044,8 @@ struct MarkBasePosFormat1
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a non-mark glyph */ /* 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); skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
do { do {
if (!skippy_iter.prev ()) return TRACE_RETURN (false); 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)); 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && baseCoverage.sanitize (c, 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)); 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 inline typename context_t::return_t dispatch (context_t *c) const
{ {
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
switch (u.format) { switch (u.format) {
case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 1: return TRACE_RETURN (c->dispatch (u.format1));
default:return TRACE_RETURN (c->default_return_value ()); 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: protected:
union { union {
USHORT format; /* Format identifier */ USHORT format; /* Format identifier */
@ -1155,7 +1142,8 @@ struct MarkLigPosFormat1
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a non-mark glyph */ /* 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); skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
if (!skippy_iter.prev ()) return TRACE_RETURN (false); 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)); 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && ligatureCoverage.sanitize (c, 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)); 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 inline typename context_t::return_t dispatch (context_t *c) const
{ {
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
switch (u.format) { switch (u.format) {
case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 1: return TRACE_RETURN (c->dispatch (u.format1));
default:return TRACE_RETURN (c->default_return_value ()); 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: protected:
union { union {
USHORT format; /* Format identifier */ USHORT format; /* Format identifier */
@ -1271,7 +1252,8 @@ struct MarkMarkPosFormat1
if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false); if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a suitable mark glyph until a non-mark glyph */ /* 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); skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
if (!skippy_iter.prev ()) return TRACE_RETURN (false); 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)); 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, this) && return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, this) &&
mark2Coverage.sanitize (c, this) && mark1Array.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 inline typename context_t::return_t dispatch (context_t *c) const
{ {
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
switch (u.format) { switch (u.format) {
case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 1: return TRACE_RETURN (c->dispatch (u.format1));
default:return TRACE_RETURN (c->default_return_value ()); 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: protected:
union { union {
USHORT format; /* Format identifier */ 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 inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
{ {
TRACE_DISPATCH (this, lookup_type); 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) { switch (lookup_type) {
case Single: return TRACE_RETURN (u.single.dispatch (c)); case Single: return TRACE_RETURN (u.single.dispatch (c));
case Pair: return TRACE_RETURN (u.pair.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: protected:
union { union {
struct { USHORT sub_format;
USHORT sub_format;
} header;
SinglePos single; SinglePos single;
PairPos pair; PairPos pair;
CursivePos cursive; CursivePos cursive;
@ -1447,48 +1404,37 @@ struct PosLookupSubTable
ExtensionPos extension; ExtensionPos extension;
} u; } u;
public: public:
DEFINE_SIZE_UNION (2, header.sub_format); DEFINE_SIZE_UNION (2, sub_format);
}; };
struct PosLookup : Lookup struct PosLookup : Lookup
{ {
inline const PosLookupSubTable& get_subtable (unsigned int i) const 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 inline bool is_reverse (void) const
{ {
return false; 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 inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
{ {
TRACE_COLLECT_GLYPHS (this); TRACE_COLLECT_GLYPHS (this);
c->set_recurse_func (NULL);
return TRACE_RETURN (dispatch (c)); return TRACE_RETURN (dispatch (c));
} }
template <typename set_t> template <typename set_t>
inline void add_coverage (set_t *glyphs) const inline void add_coverage (set_t *glyphs) const
{ {
hb_get_coverage_context_t c; hb_add_coverage_context_t<set_t> c (glyphs);
const Coverage *last = NULL; dispatch (&c);
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));
} }
static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index); 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> template <typename context_t>
inline typename context_t::return_t dispatch (context_t *c) const inline typename context_t::return_t dispatch (context_t *c) const
{ { return Lookup::dispatch<PosLookupSubTable> (c); }
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 ());
}
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTable> > (subTable); const OffsetArrayOf<PosLookupSubTable> &list = get_subtables<PosLookupSubTable> ();
return TRACE_RETURN (list.sanitize (c, this, get_type ())); 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_start (hb_font_t *font, hb_buffer_t *buffer);
static inline void position_finish (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); TRACE_SANITIZE (this);
if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); 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)); return TRACE_RETURN (list.sanitize (c, this));
} }
public: public:
@ -1632,8 +1570,8 @@ template <typename context_t>
const PosLookup &l = gpos.get_lookup (lookup_index); const PosLookup &l = gpos.get_lookup (lookup_index);
unsigned int saved_lookup_props = c->lookup_props; unsigned int saved_lookup_props = c->lookup_props;
c->set_lookup (l); c->set_lookup (l);
bool ret = l.apply_once (c); bool ret = l.dispatch (c);
c->lookup_props = saved_lookup_props; c->set_lookup_props (saved_lookup_props);
return ret; return ret;
} }

View File

@ -97,7 +97,8 @@ struct SingleSubstFormat1
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c)); return TRACE_RETURN (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
} }
@ -173,7 +174,8 @@ struct SingleSubstFormat2
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && substitute.sanitize (c)); 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 inline typename context_t::return_t dispatch (context_t *c) const
{ {
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
switch (u.format) { switch (u.format) {
case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 1: return TRACE_RETURN (c->dispatch (u.format1));
case 2: return TRACE_RETURN (c->dispatch (u.format2)); 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: protected:
union { union {
USHORT format; /* Format identifier */ USHORT format; /* Format identifier */
@ -312,7 +305,8 @@ struct Sequence
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (substitute.sanitize (c)); return TRACE_RETURN (substitute.sanitize (c));
} }
@ -384,7 +378,8 @@ struct MultipleSubstFormat1
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && sequence.sanitize (c, 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 inline typename context_t::return_t dispatch (context_t *c) const
{ {
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
switch (u.format) { switch (u.format) {
case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 1: return TRACE_RETURN (c->dispatch (u.format1));
default:return TRACE_RETURN (c->default_return_value ()); 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: protected:
union { union {
USHORT format; /* Format identifier */ USHORT format; /* Format identifier */
@ -535,7 +522,8 @@ struct AlternateSubstFormat1
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && alternateSet.sanitize (c, 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 inline typename context_t::return_t dispatch (context_t *c) const
{ {
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
switch (u.format) { switch (u.format) {
case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 1: return TRACE_RETURN (c->dispatch (u.format1));
default:return TRACE_RETURN (c->default_return_value ()); 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: protected:
union { union {
USHORT format; /* Format identifier */ USHORT format; /* Format identifier */
@ -686,7 +666,8 @@ struct Ligature
} }
public: public:
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (ligGlyph.sanitize (c) && component.sanitize (c)); return TRACE_RETURN (ligGlyph.sanitize (c) && component.sanitize (c));
} }
@ -764,7 +745,8 @@ struct LigatureSet
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (ligature.sanitize (c, this)); return TRACE_RETURN (ligature.sanitize (c, this));
} }
@ -848,7 +830,8 @@ struct LigatureSubstFormat1
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && ligatureSet.sanitize (c, 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 inline typename context_t::return_t dispatch (context_t *c) const
{ {
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
switch (u.format) { switch (u.format) {
case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 1: return TRACE_RETURN (c->dispatch (u.format1));
default:return TRACE_RETURN (c->default_return_value ()); 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: protected:
union { union {
USHORT format; /* Format identifier */ USHORT format; /* Format identifier */
@ -1017,14 +992,15 @@ struct ReverseChainSingleSubstFormat1
return TRACE_RETURN (false); return TRACE_RETURN (false);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
return TRACE_RETURN (false); return TRACE_RETURN (false);
OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
if (!lookahead.sanitize (c, this)) if (!lookahead.sanitize (c, this))
return TRACE_RETURN (false); 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)); return TRACE_RETURN (substitute.sanitize (c));
} }
@ -1054,21 +1030,13 @@ struct ReverseChainSingleSubst
inline typename context_t::return_t dispatch (context_t *c) const inline typename context_t::return_t dispatch (context_t *c) const
{ {
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
switch (u.format) { switch (u.format) {
case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 1: return TRACE_RETURN (c->dispatch (u.format1));
default:return TRACE_RETURN (c->default_return_value ()); 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: protected:
union { union {
USHORT format; /* Format identifier */ 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 inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
{ {
TRACE_DISPATCH (this, lookup_type); 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) { switch (lookup_type) {
case Single: return TRACE_RETURN (u.single.dispatch (c)); case Single: return TRACE_RETURN (u.single.dispatch (c));
case Multiple: return TRACE_RETURN (u.multiple.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: protected:
union { union {
struct { USHORT sub_format;
USHORT sub_format;
} header;
SingleSubst single; SingleSubst single;
MultipleSubst multiple; MultipleSubst multiple;
AlternateSubst alternate; AlternateSubst alternate;
@ -1146,14 +1097,14 @@ struct SubstLookupSubTable
ReverseChainSingleSubst reverseChainContextSingle; ReverseChainSingleSubst reverseChainContextSingle;
} u; } u;
public: public:
DEFINE_SIZE_UNION (2, header.sub_format); DEFINE_SIZE_UNION (2, sub_format);
}; };
struct SubstLookup : Lookup struct SubstLookup : Lookup
{ {
inline const SubstLookupSubTable& get_subtable (unsigned int i) const 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) inline static bool lookup_type_is_reverse (unsigned int lookup_type)
{ return lookup_type == SubstLookupSubTable::ReverseChainSingle; } { return lookup_type == SubstLookupSubTable::ReverseChainSingle; }
@ -1166,6 +1117,12 @@ struct SubstLookup : Lookup
return lookup_type_is_reverse (type); 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 inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const
{ {
TRACE_CLOSURE (this); TRACE_CLOSURE (this);
@ -1183,39 +1140,24 @@ struct SubstLookup : Lookup
template <typename set_t> template <typename set_t>
inline void add_coverage (set_t *glyphs) const inline void add_coverage (set_t *glyphs) const
{ {
hb_get_coverage_context_t c; hb_add_coverage_context_t<set_t> c (glyphs);
const Coverage *last = NULL; dispatch (&c);
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 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); TRACE_WOULD_APPLY (this);
if (unlikely (!c->len)) return TRACE_RETURN (false); 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)); 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); static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c, inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c,
unsigned int i) 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, inline bool serialize_single (hb_serialize_context_t *c,
uint32_t lookup_props, uint32_t lookup_props,
@ -1274,24 +1216,14 @@ struct SubstLookup : Lookup
template <typename context_t> template <typename context_t>
inline typename context_t::return_t dispatch (context_t *c) const inline typename context_t::return_t dispatch (context_t *c) const
{ { return Lookup::dispatch<SubstLookupSubTable> (c); }
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 ());
}
inline bool sanitize (hb_sanitize_context_t *c) inline bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
OffsetArrayOf<SubstLookupSubTable> &list = CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable); const OffsetArrayOf<SubstLookupSubTable> &list = get_subtables<SubstLookupSubTable> ();
if (unlikely (!list.sanitize (c, this, get_type ()))) return TRACE_RETURN (false); if (unlikely (!dispatch (c))) return TRACE_RETURN (false);
if (unlikely (get_type () == SubstLookupSubTable::Extension)) 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_start (hb_font_t *font, hb_buffer_t *buffer);
static inline void substitute_finish (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); TRACE_SANITIZE (this);
if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); 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)); return TRACE_RETURN (list.sanitize (c, this));
} }
public: 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 (); unsigned int type = get_type ();
if (unlikely (type == SubstLookupSubTable::Extension)) 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); return SubstLookup::lookup_type_is_reverse (type);
} }
@ -1380,8 +1313,8 @@ template <typename context_t>
const SubstLookup &l = gsub.get_lookup (lookup_index); const SubstLookup &l = gsub.get_lookup (lookup_index);
unsigned int saved_lookup_props = c->lookup_props; unsigned int saved_lookup_props = c->lookup_props;
c->set_lookup (l); c->set_lookup (l);
bool ret = l.apply_once (c); bool ret = l.dispatch (c);
c->lookup_props = saved_lookup_props; c->set_lookup_props (saved_lookup_props);
return ret; return ret;
} }

View File

@ -37,12 +37,6 @@
namespace OT { 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 #ifndef HB_DEBUG_CLOSURE
#define HB_DEBUG_CLOSURE (HB_DEBUG+0) #define HB_DEBUG_CLOSURE (HB_DEBUG+0)
#endif #endif
@ -58,6 +52,8 @@ struct hb_closure_context_t
static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE; static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE;
typedef hb_void_t return_t; typedef hb_void_t return_t;
typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index); 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> template <typename T>
inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; } inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; }
static return_t default_return_value (void) { 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"; } inline const char *get_name (void) { return "WOULD_APPLY"; }
static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY; static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY;
typedef bool return_t; typedef bool return_t;
template <typename T, typename F>
inline bool may_dispatch (const T *obj, const F *format) { return true; }
template <typename T> template <typename T>
inline return_t dispatch (const T &obj) { return obj.would_apply (this); } inline return_t dispatch (const T &obj) { return obj.would_apply (this); }
static return_t default_return_value (void) { return false; } 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; static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS;
typedef hb_void_t return_t; typedef hb_void_t return_t;
typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index); 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> template <typename T>
inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; } inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; }
static return_t default_return_value (void) { 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) #define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0)
#endif #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"; } inline const char *get_name (void) { return "GET_COVERAGE"; }
static const unsigned int max_debug_depth = HB_DEBUG_GET_COVERAGE; static const unsigned int max_debug_depth = HB_DEBUG_GET_COVERAGE;
typedef const Coverage &return_t; 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> template <typename T>
inline return_t dispatch (const T &obj) { return obj.get_coverage (); } inline return_t dispatch (const T &obj) { return obj.get_coverage (); }
static return_t default_return_value (void) { return Null(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) {} debug_depth (0) {}
set_t *set;
unsigned int debug_depth; unsigned int debug_depth;
}; };
@ -260,61 +270,6 @@ struct hb_get_coverage_context_t
struct hb_apply_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 struct matcher_t
{ {
inline matcher_t (void) : inline matcher_t (void) :
@ -390,29 +345,24 @@ struct hb_apply_context_t
const void *match_data; const void *match_data;
}; };
struct skipping_forward_iterator_t struct skipping_iterator_t
{ {
inline skipping_forward_iterator_t (hb_apply_context_t *c_, inline void init (hb_apply_context_t *c_, bool context_match = false)
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)
{ {
c = c_;
match_glyph_data = NULL,
matcher.set_match_func (NULL, NULL);
matcher.set_lookup_props (c->lookup_props); matcher.set_lookup_props (c->lookup_props);
/* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
matcher.set_ignore_zwnj (context_match || c->table_index == 1); 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. */ /* 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); matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj);
if (!context_match) matcher.set_mask (context_match ? -1 : c->lookup_mask);
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_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, inline void set_match_func (matcher_t::match_func_t match_func,
const void *match_data, const void *match_data,
const USHORT glyph_data[]) const USHORT glyph_data[])
@ -421,12 +371,21 @@ struct hb_apply_context_t
match_glyph_data = glyph_data; 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 void reject (void) { num_items++; match_glyph_data--; }
inline bool next (void) inline bool next (void)
{ {
assert (num_items > 0); assert (num_items > 0);
while (!has_no_chance ()) while (idx + num_items < end)
{ {
idx++; idx++;
const hb_glyph_info_t &info = c->buffer->info[idx]; const hb_glyph_info_t &info = c->buffer->info[idx];
@ -450,53 +409,10 @@ struct hb_apply_context_t
} }
return false; 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) inline bool prev (void)
{ {
assert (num_items > 0); assert (num_items > 0);
while (!has_no_chance ()) while (idx >= num_items)
{ {
idx--; idx--;
const hb_glyph_info_t &info = c->buffer->out_info[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; const USHORT *match_glyph_data;
unsigned int num_items; 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 inline bool
match_properties_mark (hb_codepoint_t glyph, match_properties_mark (hb_codepoint_t glyph,
unsigned int glyph_props, 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_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); 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: * 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); 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); 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++) for (unsigned int i = 0; i < count; i++)
if (!skippy_iter.prev ()) if (!skippy_iter.prev ())
@ -930,9 +913,9 @@ static inline bool match_lookahead (hb_apply_context_t *c,
{ {
TRACE_APPLY (NULL); 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); 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++) for (unsigned int i = 0; i < count; i++)
if (!skippy_iter.next ()) if (!skippy_iter.next ())
@ -945,7 +928,8 @@ static inline bool match_lookahead (hb_apply_context_t *c,
struct LookupRecord struct LookupRecord
{ {
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this)); return TRACE_RETURN (c->check_struct (this));
} }
@ -1168,7 +1152,8 @@ struct Rule
} }
public: public:
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return inputCount.sanitize (c) return inputCount.sanitize (c)
&& lookupCount.sanitize (c) && lookupCount.sanitize (c)
@ -1232,7 +1217,8 @@ struct RuleSet
return TRACE_RETURN (false); return TRACE_RETURN (false);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (rule.sanitize (c, this)); return TRACE_RETURN (rule.sanitize (c, this));
} }
@ -1314,7 +1300,8 @@ struct ContextFormat1
return TRACE_RETURN (rule_set.apply (c, lookup_context)); 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); TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, 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)); 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); TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, 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)); 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); TRACE_SANITIZE (this);
if (!c->check_struct (this)) return TRACE_RETURN (false); if (!c->check_struct (this)) return TRACE_RETURN (false);
unsigned int count = glyphCount; unsigned int count = glyphCount;
@ -1502,7 +1491,7 @@ struct ContextFormat3
if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return TRACE_RETURN (false); if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return TRACE_RETURN (false);
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
if (!coverageZ[i].sanitize (c, this)) return TRACE_RETURN (false); 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)); 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 inline typename context_t::return_t dispatch (context_t *c) const
{ {
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
switch (u.format) { switch (u.format) {
case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 1: return TRACE_RETURN (c->dispatch (u.format1));
case 2: return TRACE_RETURN (c->dispatch (u.format2)); 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: protected:
union { union {
USHORT format; /* Format identifier */ USHORT format; /* Format identifier */
@ -1726,14 +1705,15 @@ struct ChainRule
lookup.array, lookup_context)); lookup.array, lookup_context));
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (!backtrack.sanitize (c)) return TRACE_RETURN (false); 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); 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); 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)); return TRACE_RETURN (lookup.sanitize (c));
} }
@ -1795,7 +1775,8 @@ struct ChainRuleSet
return TRACE_RETURN (false); return TRACE_RETURN (false);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (rule.sanitize (c, this)); return TRACE_RETURN (rule.sanitize (c, this));
} }
@ -1874,7 +1855,8 @@ struct ChainContextFormat1
return TRACE_RETURN (rule_set.apply (c, lookup_context)); 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); TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, 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)); 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); TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.sanitize (c, this) && return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.sanitize (c, this) &&
inputClassDef.sanitize (c, this) && lookaheadClassDef.sanitize (c, this) && inputClassDef.sanitize (c, this) && lookaheadClassDef.sanitize (c, this) &&
@ -2105,15 +2088,16 @@ struct ChainContextFormat3
lookup.len, lookup.array, lookup_context)); 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); TRACE_SANITIZE (this);
if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false); 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.sanitize (c, this)) return TRACE_RETURN (false);
if (!input.len) return TRACE_RETURN (false); /* To be consistent with Context. */ 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); 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)); return TRACE_RETURN (lookup.sanitize (c));
} }
@ -2144,6 +2128,7 @@ struct ChainContext
inline typename context_t::return_t dispatch (context_t *c) const inline typename context_t::return_t dispatch (context_t *c) const
{ {
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
switch (u.format) { switch (u.format) {
case 1: return TRACE_RETURN (c->dispatch (u.format1)); case 1: return TRACE_RETURN (c->dispatch (u.format1));
case 2: return TRACE_RETURN (c->dispatch (u.format2)); 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: protected:
union { union {
USHORT format; /* Format identifier */ USHORT format; /* Format identifier */
@ -2173,14 +2147,32 @@ struct ChainContext
}; };
template <typename T>
struct ExtensionFormat1 struct ExtensionFormat1
{ {
inline unsigned int get_type (void) const { return extensionLookupType; } 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); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this)); return TRACE_RETURN (c->check_struct (this) && extensionOffset != 0);
} }
protected: protected:
@ -2204,49 +2196,30 @@ struct Extension
default:return 0; 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> template <typename X>
inline const X& get_subtable (void) const inline const X& get_subtable (void) const
{ {
unsigned int offset = get_offset (); switch (u.format) {
if (unlikely (!offset)) return Null(typename T::LookupSubTable); case 1: return u.format1.template get_subtable<typename T::LookupSubTable> ();
return StructAtOffset<typename T::LookupSubTable> (this, offset); default:return Null(typename T::LookupSubTable);
}
} }
template <typename context_t> template <typename context_t>
inline typename context_t::return_t dispatch (context_t *c) const inline typename context_t::return_t dispatch (context_t *c) const
{ {
return get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ()); TRACE_DISPATCH (this, u.format);
} if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
inline bool sanitize_self (hb_sanitize_context_t *c) {
TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) { switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c)); case 1: return TRACE_RETURN (u.format1.dispatch (c));
default:return TRACE_RETURN (true); 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: protected:
union { union {
USHORT format; /* Format identifier */ USHORT format; /* Format identifier */
ExtensionFormat1 format1; ExtensionFormat1<T> format1;
} u; } u;
}; };
@ -2291,7 +2264,8 @@ struct GSUBGPOS
inline const Lookup& get_lookup (unsigned int i) const inline const Lookup& get_lookup (unsigned int i) const
{ return (this+lookupList)[i]; } { return (this+lookupList)[i]; }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) && return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) &&
scriptList.sanitize (c, this) && scriptList.sanitize (c, this) &&

View File

@ -54,7 +54,8 @@ typedef OffsetListOf<PosLookup> JstfMax;
struct JstfPriority struct JstfPriority
{ {
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && return TRACE_RETURN (c->check_struct (this) &&
shrinkageEnableGSUB.sanitize (c, this) && shrinkageEnableGSUB.sanitize (c, this) &&
@ -123,7 +124,8 @@ struct JstfPriority
struct JstfLangSys : OffsetListOf<JstfPriority> struct JstfLangSys : OffsetListOf<JstfPriority>
{ {
inline bool sanitize (hb_sanitize_context_t *c, 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); TRACE_SANITIZE (this);
return TRACE_RETURN (OffsetListOf<JstfPriority>::sanitize (c)); 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 const JstfLangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
inline bool sanitize (hb_sanitize_context_t *c, 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); TRACE_SANITIZE (this);
return TRACE_RETURN (extenderGlyphs.sanitize (c, this) && return TRACE_RETURN (extenderGlyphs.sanitize (c, this) &&
defaultLangSys.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 inline bool find_script_index (hb_tag_t tag, unsigned int *index) const
{ return scriptList.find_index (tag, index); } { 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); TRACE_SANITIZE (this);
return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) && return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) &&
scriptList.sanitize (c, this)); scriptList.sanitize (c, this));

View File

@ -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; hb_set_digest_t digest;
}; };

View File

@ -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); 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 void
@ -829,26 +829,83 @@ struct GPOSProxy
}; };
template <typename Lookup> template <typename Obj>
static inline bool apply_once (OT::hb_apply_context_t *c, static inline bool
const Lookup &lookup) 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)) bool ret = false;
return false; hb_buffer_t *buffer = c->buffer;
return lookup.dispatch (c); 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 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, apply_string (OT::hb_apply_context_t *c,
const typename Proxy::Lookup &lookup, const typename Proxy::Lookup &lookup,
const hb_ot_layout_lookup_accelerator_t &accel) const hb_ot_layout_lookup_accelerator_t &accel)
{ {
bool ret = false;
hb_buffer_t *buffer = c->buffer; hb_buffer_t *buffer = c->buffer;
if (unlikely (!buffer->len || !c->lookup_mask)) if (unlikely (!buffer->len || !c->lookup_mask))
return false; return;
c->set_lookup (lookup); c->set_lookup (lookup);
@ -859,21 +916,20 @@ apply_string (OT::hb_apply_context_t *c,
buffer->clear_output (); buffer->clear_output ();
buffer->idx = 0; buffer->idx = 0;
while (buffer->idx < buffer->len) bool ret;
if (lookup.get_subtable_count () == 1)
{ {
if (accel.digest.may_have (buffer->cur().codepoint) && hb_apply_forward_context_t c_forward (c, accel);
(buffer->cur().mask & c->lookup_mask) && ret = lookup.dispatch (&c_forward);
apply_once (c, lookup))
ret = true;
else
buffer->next_glyph ();
} }
else
ret = apply_forward (c, lookup, accel);
if (ret) if (ret)
{ {
if (!Proxy::inplace) if (!Proxy::inplace)
buffer->swap_buffers (); buffer->swap_buffers ();
else else
assert (!buffer->has_separate_output ()); assert (!buffer->has_separate_output ());
} }
} }
else else
@ -882,20 +938,9 @@ apply_string (OT::hb_apply_context_t *c,
if (Proxy::table_index == 0) if (Proxy::table_index == 0)
buffer->remove_output (); buffer->remove_output ();
buffer->idx = buffer->len - 1; 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--;
} apply_backward (c, lookup, accel);
while ((int) buffer->idx >= 0);
} }
return ret;
} }
template <typename Proxy> template <typename Proxy>

View File

@ -43,11 +43,13 @@ struct maxp
{ {
static const hb_tag_t tableTag = HB_OT_TAG_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; return numGlyphs;
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && return TRACE_RETURN (c->check_struct (this) &&
likely (version.major == 1 || (version.major == 0 && version.minor == 0x5000u))); likely (version.major == 1 || (version.major == 0 && version.minor == 0x5000u)));

View File

@ -56,7 +56,8 @@ struct NameRecord
return 0; 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); TRACE_SANITIZE (this);
/* We can check from base all the way up to the end of string... */ /* 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)); 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 inline unsigned int get_size (void) const
{ return min_size + count * nameRecord[0].min_size; } { 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); TRACE_SANITIZE (this);
char *string_pool = (char *) this + stringOffset; char *string_pool = (char *) this + stringOffset;
unsigned int _count = count; unsigned int _count = count;
@ -110,7 +111,8 @@ struct name
return TRACE_RETURN (true); return TRACE_RETURN (true);
} }
inline bool sanitize (hb_sanitize_context_t *c) { inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && return TRACE_RETURN (c->check_struct (this) &&
likely (format == 0 || format == 1) && likely (format == 0 || format == 1) &&

View File

@ -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); OT::hb_apply_context_t c (1, font, buffer);
c.set_lookup_mask (plan->kern_mask); c.set_lookup_mask (plan->kern_mask);
c.set_lookup_props (OT::LookupFlag::IgnoreMarks); 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; unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info; hb_glyph_info_t *info = buffer->info;
hb_glyph_position_t *pos = buffer->pos; hb_glyph_position_t *pos = buffer->pos;
for (unsigned int idx = 0; idx < count;) 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 ()) if (!skippy_iter.next ())
{ {
idx++; idx++;

View File

@ -573,6 +573,30 @@ _hb_debug (unsigned int level,
#define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT)) #define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT))
#define DEBUG_ENABLED(WHAT) (DEBUG_LEVEL_ENABLED (WHAT, 0)) #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 template <int max_level> static inline void
_hb_debug_msg_va (const char *what, _hb_debug_msg_va (const char *what,
const void *obj, const void *obj,
@ -618,27 +642,13 @@ _hb_debug_msg_va (const char *what,
} else } else
fprintf (stderr, " " VRBAR LBAR); fprintf (stderr, " " VRBAR LBAR);
if (func) _hb_print_func (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);
}
if (message) if (message)
{
fprintf (stderr, ": ");
vfprintf (stderr, message, ap); vfprintf (stderr, message, ap);
}
fprintf (stderr, "\n"); fprintf (stderr, "\n");
} }
@ -810,7 +820,7 @@ hb_in_range (T u, T lo, T hi)
/* The sizeof() is here to force template instantiation. /* The sizeof() is here to force template instantiation.
* I'm sure there are better ways to do this but can't think of * 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 * 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. */ * to generate a warning than unused variables. */
ASSERT_STATIC (sizeof (hb_assert_unsigned_t<T>) >= 0); ASSERT_STATIC (sizeof (hb_assert_unsigned_t<T>) >= 0);

View File

@ -145,6 +145,8 @@ typedef hb_set_digest_combiner_t
struct hb_set_t struct hb_set_t
{ {
friend struct hb_frozen_set_t;
hb_object_header_t header; hb_object_header_t header;
ASSERT_POD (); ASSERT_POD ();
bool in_error; bool in_error;
@ -326,7 +328,7 @@ struct hb_set_t
static const hb_codepoint_t INVALID = HB_SET_VALUE_INVALID; 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) { 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 mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
elt_t elts[ELTS]; /* XXX 8kb */ elt_t elts[ELTS]; /* XXX 8kb */
@ -335,6 +337,59 @@ struct hb_set_t
ASSERT_STATIC (sizeof (elt_t) * 8 * ELTS > MAX_G); 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 */ #endif /* HB_SET_PRIVATE_HH */

View File

@ -38,9 +38,9 @@ HB_BEGIN_DECLS
#define HB_VERSION_MAJOR 0 #define HB_VERSION_MAJOR 0
#define HB_VERSION_MINOR 9 #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) \ #define HB_VERSION_ATLEAST(major,minor,micro) \
((major)*10000+(minor)*100+(micro) <= \ ((major)*10000+(minor)*100+(micro) <= \

View File

@ -68,7 +68,7 @@ static int init_libthai() {
return 0; 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; hb_uint32 i;
unsigned char *result = (unsigned char *)cstr; 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++) { for (c = 0; c < 0x80; c++) {
if ( glyph_map[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; return 0;
} }
} }

View File

@ -65,6 +65,7 @@ import android.view.ViewConfiguration;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.LinearLayout;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@ -788,7 +789,29 @@ public class QtActivityDelegate
0, 0, 0, 0,
metrics.xdpi, metrics.ydpi, metrics.scaledDensity); metrics.xdpi, metrics.ydpi, metrics.scaledDensity);
} }
ViewGroup layout = null;
m_layout = new QtLayout(m_activity); 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_editText = new QtEditText(m_activity, this);
m_imm = (InputMethodManager)m_activity.getSystemService(Context.INPUT_METHOD_SERVICE); m_imm = (InputMethodManager)m_activity.getSystemService(Context.INPUT_METHOD_SERVICE);
m_surfaces = new HashMap<Integer, QtSurface>(); m_surfaces = new HashMap<Integer, QtSurface>();
@ -811,7 +834,7 @@ public class QtActivityDelegate
Log.w("Qt A11y", "Unknown exception: " + e.toString()); Log.w("Qt A11y", "Unknown exception: " + e.toString());
} }
m_activity.setContentView(m_layout, m_activity.setContentView(layout,
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT)); ViewGroup.LayoutParams.MATCH_PARENT));

View File

@ -279,12 +279,14 @@ public class QtNative
if (action == MotionEvent.ACTION_MOVE) { if (action == MotionEvent.ACTION_MOVE) {
int hsz = event.getHistorySize(); int hsz = event.getHistorySize();
if (hsz > 0) { if (hsz > 0) {
if (event.getX(index) != event.getHistoricalX(index, hsz-1) float x = event.getX(index);
|| event.getY(index) != event.getHistoricalY(index, hsz-1)) { float y = event.getY(index);
return 1; for (int h = 0; h < hsz; ++h) {
} else { if ( event.getHistoricalX(index, h) != x ||
return 2; event.getHistoricalY(index, h) != y )
return 1;
} }
return 2;
} }
return 1; return 1;
} }

View File

@ -44,6 +44,10 @@
signal is sent! --> signal is sent! -->
<meta-data android:name="android.app.background_running" android:value="false"/> <meta-data android:name="android.app.background_running" android:value="false"/>
<!-- Background running --> <!-- 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> </activity>
</application> </application>
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="14"/> <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="14"/>

View File

@ -269,7 +269,7 @@ function(QT5_ADD_RESOURCES outfiles )
set(rcc_files ${_RCC_UNPARSED_ARGUMENTS}) set(rcc_files ${_RCC_UNPARSED_ARGUMENTS})
set(rcc_options ${_RCC_OPTIONS}) 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") message(WARNING "Use qt5_add_binary_resources for binary option")
endif() endif()

View File

@ -36,7 +36,8 @@ exampledirs += \
../ \ ../ \
snippets \ snippets \
../../../examples/corelib \ ../../../examples/corelib \
../../../examples/network/dnslookup ../../../examples/network/dnslookup \
../../../examples/widgets/tools
imagedirs += images imagedirs += images

View File

@ -129,7 +129,9 @@
\li \list \li \list
\li Date (QDate) \li Date (QDate)
\li Time (QTime) \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 \endlist
\row \li QEasingCurve \row \li QEasingCurve
\li \list \li \list
@ -145,11 +147,19 @@
\row \li QFont \row \li QFont
\li \list \li \list
\li The family (QString) \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 hint (quint8)
\li The style strategy (quint16)
\li The char set (quint8) \li The char set (quint8)
\li The weight (quint8) \li The weight (quint8)
\li The font bits (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 \endlist
\row \li QHash<Key, T> \row \li QHash<Key, T>
\li \list \li \list

View File

@ -1164,7 +1164,6 @@
const bool valueOfExpression = Expr;\ const bool valueOfExpression = Expr;\
Q_ASSERT_X(valueOfExpression, "Q_ASSUME()", "Assumption in Q_ASSUME(\"" #Expr "\") was not correct");\ Q_ASSERT_X(valueOfExpression, "Q_ASSUME()", "Assumption in Q_ASSUME(\"" #Expr "\") was not correct");\
Q_ASSUME_IMPL(valueOfExpression);\ 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) } while (0)

View File

@ -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(Q_ASSERT_X)
# if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) # 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 # else
# define Q_ASSERT_X(cond, where, what) ((!(cond)) ? qt_assert_x(where, what,__FILE__,__LINE__) : qt_noop()) # define Q_ASSERT_X(cond, where, what) ((!(cond)) ? qt_assert_x(where, what,__FILE__,__LINE__) : qt_noop())
# endif # endif

View File

@ -63,12 +63,16 @@ extern void qDumpCPUFeatures(); // in qsimd.cpp
struct QLibrarySettings struct QLibrarySettings
{ {
QLibrarySettings(); QLibrarySettings();
void load();
QScopedPointer<QSettings> settings; QScopedPointer<QSettings> settings;
#ifdef QT_BUILD_QMAKE #ifdef QT_BUILD_QMAKE
bool haveDevicePaths; bool haveDevicePaths;
bool haveEffectiveSourcePaths; bool haveEffectiveSourcePaths;
bool haveEffectivePaths; bool haveEffectivePaths;
bool havePaths; bool havePaths;
#else
bool reloadOnQAppAvailable;
#endif #endif
}; };
Q_GLOBAL_STATIC(QLibrarySettings, qt_library_settings) Q_GLOBAL_STATIC(QLibrarySettings, qt_library_settings)
@ -93,16 +97,31 @@ public:
static QSettings *configuration() static QSettings *configuration()
{ {
QLibrarySettings *ls = qt_library_settings(); 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"; static const char platformsSection[] = "Platforms";
QLibrarySettings::QLibrarySettings() 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 #ifndef QT_BUILD_QMAKE
reloadOnQAppAvailable = (settings.data() == 0 && QCoreApplication::instance() == 0);
bool haveDevicePaths; bool haveDevicePaths;
bool haveEffectivePaths; bool haveEffectivePaths;
bool havePaths; bool havePaths;
@ -139,33 +158,35 @@ QLibrarySettings::QLibrarySettings()
QSettings *QLibraryInfoPrivate::findConfiguration() QSettings *QLibraryInfoPrivate::findConfiguration()
{ {
QString qtconfig = QStringLiteral(":/qt/etc/qt.conf"); QString qtconfig = QStringLiteral(":/qt/etc/qt.conf");
#ifdef QT_BUILD_QMAKE
if(!QFile::exists(qtconfig))
qtconfig = qmake_libraryInfoFile();
#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);
}
}
if (qtconfig.isEmpty())
#endif
{
QDir pwd(QCoreApplication::applicationDirPath());
qtconfig = pwd.filePath(QLatin1String("qt.conf"));
}
}
#endif
if (QFile::exists(qtconfig)) if (QFile::exists(qtconfig))
return new QSettings(qtconfig, QSettings::IniFormat); return new QSettings(qtconfig, QSettings::IniFormat);
#ifdef QT_BUILD_QMAKE
qtconfig = qmake_libraryInfoFile();
if (QFile::exists(qtconfig))
return new QSettings(qtconfig, QSettings::IniFormat);
#else
#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);
if (QFile::exists(qtconfig))
return new QSettings(qtconfig, QSettings::IniFormat);
}
}
#endif
if (QCoreApplication::instance()) {
QDir pwd(QCoreApplication::applicationDirPath());
qtconfig = pwd.filePath(QLatin1String("qt.conf"));
if (QFile::exists(qtconfig))
return new QSettings(qtconfig, QSettings::IniFormat);
}
#endif
return 0; //no luck return 0; //no luck
} }

View File

@ -36,10 +36,17 @@
# define _POSIX_C_SOURCE 200809L # define _POSIX_C_SOURCE 200809L
#endif #endif
#if !defined(_XOPEN_SOURCE) && !defined(__QNXNTO__) && !defined(ANDROID) #if !defined(_XOPEN_SOURCE) && !defined(__QNXNTO__) && !defined(ANDROID)
# define _XOPEN_SOURCE 500 # define _XOPEN_SOURCE 700
#endif #endif
#include <QtCore/qatomic.h> #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) #if defined(QT_NO_DEBUG) && !defined(NDEBUG)
# define NDEBUG # define NDEBUG

View File

@ -586,7 +586,7 @@ qint64 QIODevice::pos() const
{ {
Q_D(const QIODevice); Q_D(const QIODevice);
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p QIODevice::pos() == %d\n", this, int(d->pos)); printf("%p QIODevice::pos() == %lld\n", this, d->pos);
#endif #endif
return d->pos; return d->pos;
} }
@ -629,31 +629,30 @@ bool QIODevice::seek(qint64 pos)
return false; return false;
} }
if (pos < 0) { if (pos < 0) {
qWarning("QIODevice::seek: Invalid pos: %d", int(pos)); qWarning("QIODevice::seek: Invalid pos: %lld", pos);
return false; return false;
} }
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p QIODevice::seek(%d), before: d->pos = %d, d->buffer.size() = %d\n", printf("%p QIODevice::seek(%lld), before: d->pos = %lld, d->buffer.size() = %lld\n",
this, int(pos), int(d->pos), d->buffer.size()); this, pos, d->pos, d->buffer.size());
#endif #endif
qint64 offset = pos - d->pos; qint64 offset = pos - d->pos;
d->pos = pos; d->pos = pos;
d->devicePos = pos; d->devicePos = pos;
if (offset < 0 if (offset < 0 || offset >= d->buffer.size())
|| offset >= qint64(d->buffer.size()))
// When seeking backwards, an operation that is only allowed for // When seeking backwards, an operation that is only allowed for
// random-access devices, the buffer is cleared. The next read // random-access devices, the buffer is cleared. The next read
// operation will then refill the buffer. We can optimize this, if we // operation will then refill the buffer. We can optimize this, if we
// find that seeking backwards becomes a significant performance hit. // find that seeking backwards becomes a significant performance hit.
d->buffer.clear(); d->buffer.clear();
else if (!d->buffer.isEmpty()) else if (!d->buffer.isEmpty())
d->buffer.skip(int(offset)); d->buffer.skip(offset);
#if defined QIODEVICE_DEBUG #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()); d->buffer.size());
#endif #endif
return true; return true;
@ -675,8 +674,9 @@ bool QIODevice::atEnd() const
{ {
Q_D(const QIODevice); Q_D(const QIODevice);
#if defined QIODEVICE_DEBUG #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", printf("%p QIODevice::atEnd() returns %s, d->openMode == %d, d->pos == %lld\n", this,
int(d->openMode), int(d->pos)); (d->openMode == NotOpen || d->pos == size()) ? "true" : "false", int(d->openMode),
d->pos);
#endif #endif
return d->openMode == NotOpen || (d->buffer.isEmpty() && bytesAvailable() == 0); return d->openMode == NotOpen || (d->buffer.isEmpty() && bytesAvailable() == 0);
} }
@ -749,8 +749,8 @@ qint64 QIODevice::read(char *data, qint64 maxSize)
Q_D(QIODevice); Q_D(QIODevice);
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p QIODevice::read(%p, %d), d->pos = %d, d->buffer.size() = %d\n", printf("%p QIODevice::read(%p, %lld), d->pos = %lld, d->buffer.size() = %lld\n",
this, data, int(maxSize), int(d->pos), int(d->buffer.size())); this, data, maxSize, d->pos, d->buffer.size());
#endif #endif
const bool sequential = d->isSequential(); const bool sequential = d->isSequential();
@ -791,8 +791,8 @@ qint64 QIODevice::read(char *data, qint64 maxSize)
data += bufferReadChunkSize; data += bufferReadChunkSize;
maxSize -= bufferReadChunkSize; maxSize -= bufferReadChunkSize;
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p \treading %d bytes from buffer into position %d\n", this, printf("%p \treading %lld bytes from buffer into position %lld\n", this,
bufferReadChunkSize, int(readSoFar) - bufferReadChunkSize); bufferReadChunkSize, readSoFar - bufferReadChunkSize);
#endif #endif
} else { } else {
if (d->firstRead) { if (d->firstRead) {
@ -813,8 +813,8 @@ qint64 QIODevice::read(char *data, qint64 maxSize)
readFromDevice = readData(data, maxSize); readFromDevice = readData(data, maxSize);
deviceAtEof = (readFromDevice != maxSize); deviceAtEof = (readFromDevice != maxSize);
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p \treading %d bytes from device (total %d)\n", this, printf("%p \treading %lld bytes from device (total %lld)\n", this,
int(readFromDevice), int(readSoFar)); readFromDevice, readSoFar);
#endif #endif
if (readFromDevice > 0) { if (readFromDevice > 0) {
readSoFar += readFromDevice; readSoFar += readFromDevice;
@ -826,17 +826,17 @@ qint64 QIODevice::read(char *data, qint64 maxSize)
} }
} }
} else { } else {
const int bytesToBuffer = QIODEVICE_BUFFERSIZE; const qint64 bytesToBuffer = QIODEVICE_BUFFERSIZE;
// Try to fill QIODevice buffer by single read // Try to fill QIODevice buffer by single read
readFromDevice = readData(d->buffer.reserve(bytesToBuffer), bytesToBuffer); readFromDevice = readData(d->buffer.reserve(bytesToBuffer), bytesToBuffer);
deviceAtEof = (readFromDevice != 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 (readFromDevice > 0) {
if (!sequential) if (!sequential)
d->devicePos += readFromDevice; d->devicePos += readFromDevice;
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p \treading %d from device into buffer\n", this, printf("%p \treading %lld from device into buffer\n", this,
int(readFromDevice)); readFromDevice);
#endif #endif
continue; continue;
} }
@ -884,8 +884,8 @@ qint64 QIODevice::read(char *data, qint64 maxSize)
} }
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p \treturning %d, d->pos == %d, d->buffer.size() == %d\n", this, printf("%p \treturning %lld, d->pos == %lld, d->buffer.size() == %lld\n", this,
int(readSoFar), int(d->pos), d->buffer.size()); readSoFar, d->pos, d->buffer.size());
debugBinaryString(data - readSoFar, readSoFar); debugBinaryString(data - readSoFar, readSoFar);
#endif #endif
@ -916,8 +916,8 @@ QByteArray QIODevice::read(qint64 maxSize)
CHECK_MAXLEN(read, result); CHECK_MAXLEN(read, result);
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p QIODevice::read(%d), d->pos = %d, d->buffer.size() = %d\n", printf("%p QIODevice::read(%lld), d->pos = %lld, d->buffer.size() = %lld\n",
this, int(maxSize), int(d->pos), int(d->buffer.size())); this, maxSize, d->pos, d->buffer.size());
#else #else
Q_UNUSED(d); Q_UNUSED(d);
#endif #endif
@ -966,8 +966,8 @@ QByteArray QIODevice::readAll()
{ {
Q_D(QIODevice); Q_D(QIODevice);
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p QIODevice::readAll(), d->pos = %d, d->buffer.size() = %d\n", printf("%p QIODevice::readAll(), d->pos = %lld, d->buffer.size() = %lld\n",
this, int(d->pos), int(d->buffer.size())); this, d->pos, d->buffer.size());
#endif #endif
QByteArray result; QByteArray result;
@ -1054,8 +1054,8 @@ qint64 QIODevice::readLine(char *data, qint64 maxSize)
} }
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p QIODevice::readLine(%p, %d), d->pos = %d, d->buffer.size() = %d\n", printf("%p QIODevice::readLine(%p, %lld), d->pos = %lld, d->buffer.size() = %lld\n",
this, data, int(maxSize), int(d->pos), int(d->buffer.size())); this, data, maxSize, d->pos, d->buffer.size());
#endif #endif
// Leave room for a '\0' // Leave room for a '\0'
@ -1071,8 +1071,8 @@ qint64 QIODevice::readLine(char *data, qint64 maxSize)
if (!sequential) if (!sequential)
d->pos += readSoFar; d->pos += readSoFar;
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p \tread from buffer: %d bytes, last character read: %hhx\n", this, printf("%p \tread from buffer: %lld bytes, last character read: %hhx\n", this,
int(readSoFar), data[int(readSoFar) - 1]); readSoFar, data[readSoFar - 1]);
if (readSoFar) if (readSoFar)
debugBinaryString(data, int(readSoFar)); debugBinaryString(data, int(readSoFar));
#endif #endif
@ -1094,8 +1094,8 @@ qint64 QIODevice::readLine(char *data, qint64 maxSize)
d->baseReadLineDataCalled = false; d->baseReadLineDataCalled = false;
qint64 readBytes = readLineData(data + readSoFar, maxSize - readSoFar); qint64 readBytes = readLineData(data + readSoFar, maxSize - readSoFar);
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p \tread from readLineData: %d bytes, readSoFar = %d bytes\n", this, printf("%p \tread from readLineData: %lld bytes, readSoFar = %lld bytes\n", this,
int(readBytes), int(readSoFar)); readBytes, readSoFar);
if (readBytes > 0) { if (readBytes > 0) {
debugBinaryString(data, int(readSoFar + readBytes)); debugBinaryString(data, int(readSoFar + readBytes));
} }
@ -1122,8 +1122,8 @@ qint64 QIODevice::readLine(char *data, qint64 maxSize)
} }
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p \treturning %d, d->pos = %d, d->buffer.size() = %d, size() = %d\n", printf("%p \treturning %lld, d->pos = %lld, d->buffer.size() = %lld, size() = %lld\n",
this, int(readSoFar), int(d->pos), d->buffer.size(), int(size())); this, readSoFar, d->pos, d->buffer.size(), size());
debugBinaryString(data, int(readSoFar)); debugBinaryString(data, int(readSoFar));
#endif #endif
return readSoFar; return readSoFar;
@ -1147,8 +1147,8 @@ QByteArray QIODevice::readLine(qint64 maxSize)
CHECK_MAXLEN(readLine, result); CHECK_MAXLEN(readLine, result);
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p QIODevice::readLine(%d), d->pos = %d, d->buffer.size() = %d\n", printf("%p QIODevice::readLine(%lld), d->pos = %lld, d->buffer.size() = %lld\n",
this, int(maxSize), int(d->pos), int(d->buffer.size())); this, maxSize, d->pos, d->buffer.size());
#else #else
Q_UNUSED(d); Q_UNUSED(d);
#endif #endif
@ -1220,8 +1220,8 @@ qint64 QIODevice::readLineData(char *data, qint64 maxSize)
} }
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p QIODevice::readLineData(%p, %d), d->pos = %d, d->buffer.size() = %d, returns %d\n", printf("%p QIODevice::readLineData(%p, %lld), d->pos = %lld, d->buffer.size() = %lld, "
this, data, int(maxSize), int(d->pos), int(d->buffer.size()), int(readSoFar)); "returns %lld\n", this, data, maxSize, d->pos, d->buffer.size(), readSoFar);
#endif #endif
if (lastReadReturn != 1 && readSoFar == 0) if (lastReadReturn != 1 && readSoFar == 0)
return isSequential() ? lastReadReturn : -1; return isSequential() ? lastReadReturn : -1;

View File

@ -47,6 +47,7 @@ QT_BEGIN_NAMESPACE
\class QJsonArray \class QJsonArray
\inmodule QtCore \inmodule QtCore
\ingroup json \ingroup json
\ingroup shared
\reentrant \reentrant
\since 5.0 \since 5.0

View File

@ -47,6 +47,7 @@ QT_BEGIN_NAMESPACE
/*! \class QJsonDocument /*! \class QJsonDocument
\inmodule QtCore \inmodule QtCore
\ingroup json \ingroup json
\ingroup shared
\reentrant \reentrant
\since 5.0 \since 5.0

View File

@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE
\class QJsonObject \class QJsonObject
\inmodule QtCore \inmodule QtCore
\ingroup json \ingroup json
\ingroup shared
\reentrant \reentrant
\since 5.0 \since 5.0

View File

@ -77,6 +77,7 @@ QT_BEGIN_NAMESPACE
\class QJsonParseError \class QJsonParseError
\inmodule QtCore \inmodule QtCore
\ingroup json \ingroup json
\ingroup shared
\reentrant \reentrant
\since 5.0 \since 5.0

View File

@ -62,12 +62,14 @@ public:
class ParsedObject class ParsedObject
{ {
public: 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); void insert(uint offset);
Parser *parser; Parser *parser;
int objectPosition; int objectPosition;
QVarLengthArray<uint, 64> offsets; QVector<uint> offsets;
inline QJsonPrivate::Entry *entryAt(int i) const { inline QJsonPrivate::Entry *entryAt(int i) const {
return reinterpret_cast<QJsonPrivate::Entry *>(parser->data + objectPosition + offsets[i]); return reinterpret_cast<QJsonPrivate::Entry *>(parser->data + objectPosition + offsets[i]);

View File

@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE
\class QJsonValue \class QJsonValue
\inmodule QtCore \inmodule QtCore
\ingroup json \ingroup json
\ingroup shared
\reentrant \reentrant
\since 5.0 \since 5.0

View File

@ -2420,16 +2420,27 @@ Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive))
Returns a list of paths that the application will search when Returns a list of paths that the application will search when
dynamically loading libraries. 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 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 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 it exists (the default installation directory for plugins is \c
INSTALL/plugins, where \c INSTALL is the directory where Qt was INSTALL/plugins, where \c INSTALL is the directory where Qt was
installed). The directory of the application executable (NOT the installed). The colon separated entries of the \c QT_PLUGIN_PATH
working directory) is always added, as well as the colon separated environment variable are always added. The plugin installation
entries of the \c QT_PLUGIN_PATH environment variable. 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 If you want to iterate over the list, you can use the \l foreach
pseudo-keyword: pseudo-keyword:

View File

@ -2536,7 +2536,7 @@ QModelIndex QVariant::toModelIndex() const
\sa canConvert(), convert(), toModelIndex() \sa canConvert(), convert(), toModelIndex()
*/ */
QModelIndex QVariant::toPersistentModelIndex() const QPersistentModelIndex QVariant::toPersistentModelIndex() const
{ {
return qVariantToHelper<QPersistentModelIndex>(d, handlerManager); return qVariantToHelper<QPersistentModelIndex>(d, handlerManager);
} }

View File

@ -320,7 +320,7 @@ class Q_CORE_EXPORT QVariant
QEasingCurve toEasingCurve() const; QEasingCurve toEasingCurve() const;
QUuid toUuid() const; QUuid toUuid() const;
QModelIndex toModelIndex() const; QModelIndex toModelIndex() const;
QModelIndex toPersistentModelIndex() const; QPersistentModelIndex toPersistentModelIndex() const;
QJsonValue toJsonValue() const; QJsonValue toJsonValue() const;
QJsonObject toJsonObject() const; QJsonObject toJsonObject() const;
QJsonArray toJsonArray() const; QJsonArray toJsonArray() const;

View File

@ -44,7 +44,7 @@
to the interface class called \a ClassName. The \a Identifier must to the interface class called \a ClassName. The \a Identifier must
be unique. For example: 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 This macro is normally used right after the class definition for
\a ClassName, in a header file. See the \a ClassName, in a header file. See the

View File

@ -711,6 +711,20 @@ QThread::Priority QThread::priority() const
\sa terminate() \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 #else // QT_NO_THREAD
QThread::QThread(QObject *parent) QThread::QThread(QObject *parent)

View File

@ -90,6 +90,7 @@ public:
void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher); void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher);
bool event(QEvent *event) Q_DECL_OVERRIDE; bool event(QEvent *event) Q_DECL_OVERRIDE;
int loopLevel() const;
public Q_SLOTS: public Q_SLOTS:
void start(Priority = InheritPriority); void start(Priority = InheritPriority);

View File

@ -560,22 +560,6 @@ int QDate::daysInYear() const
January 2000 has week number 52 in the year 1999, and 31 December January 2000 has week number 52 in the year 1999, and 31 December
2002 has week number 1 in the year 2003. 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() \sa isValid()
*/ */
@ -585,46 +569,29 @@ int QDate::weekNumber(int *yearNumber) const
return 0; return 0;
int year = QDate::year(); int year = QDate::year();
int yday = dayOfYear() - 1; int yday = dayOfYear();
int wday = dayOfWeek(); int wday = dayOfWeek();
if (wday == 7)
wday = 0;
int w;
for (;;) { int week = (yday - wday + 10) / 7;
int len;
int bot;
int top;
len = isLeapYear(year) ? 366 : 365; if (week == 0) {
/* // last week of previous year
** 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) {
++year;
w = 1;
break;
}
if (yday >= bot) {
w = 1 + ((yday - bot) / 7);
break;
}
--year; --year;
yday += isLeapYear(year) ? 366 : 365; 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;
week = w;
}
Q_ASSERT(week == 53 || week == 1);
} }
if (yearNumber != 0) if (yearNumber != 0)
*yearNumber = year; *yearNumber = year;
return w; return week;
} }
#ifndef QT_NO_TEXTDATE #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 // Convert a LocalTime expressed in local msecs encoding and the corresponding
// Optionally populate the returned values from mktime for the adjusted local // daylight status into a UTC epoch msecs. Optionally populate the returned
// date and time and daylight status. Uses daylightStatus in calculation if populated. // values from mktime for the adjusted local date and time.
static qint64 localMSecsToEpochMSecs(qint64 localMsecs, QDate *localDate = 0, QTime *localTime = 0, static qint64 localMSecsToEpochMSecs(qint64 localMsecs,
QDateTimePrivate::DaylightStatus *daylightStatus = 0, QDateTimePrivate::DaylightStatus *daylightStatus,
QDate *localDate = 0, QTime *localTime = 0,
QString *abbreviation = 0, bool *ok = 0) QString *abbreviation = 0, bool *ok = 0)
{ {
QDate dt; QDate dt;
@ -2713,9 +2681,11 @@ qint64 QDateTimePrivate::toMSecsSinceEpoch() const
case Qt::UTC: case Qt::UTC:
return (m_msecs - (m_offsetFromUtc * 1000)); return (m_msecs - (m_offsetFromUtc * 1000));
case Qt::LocalTime: case Qt::LocalTime: {
// recalculate the local timezone // recalculate the local timezone
return localMSecsToEpochMSecs(m_msecs); DaylightStatus status = daylightStatus();
return localMSecsToEpochMSecs(m_msecs, &status);
}
case Qt::TimeZone: case Qt::TimeZone:
#ifndef QT_BOOTSTRAPPED #ifndef QT_BOOTSTRAPPED
@ -2785,7 +2755,7 @@ void QDateTimePrivate::refreshDateTime()
qint64 epochMSecs = 0; qint64 epochMSecs = 0;
if (m_spec == Qt::LocalTime) { if (m_spec == Qt::LocalTime) {
DaylightStatus status = daylightStatus(); DaylightStatus status = daylightStatus();
epochMSecs = localMSecsToEpochMSecs(m_msecs, &testDate, &testTime, &status); epochMSecs = localMSecsToEpochMSecs(m_msecs, &status, &testDate, &testTime);
#ifndef QT_BOOTSTRAPPED #ifndef QT_BOOTSTRAPPED
} else { } else {
epochMSecs = zoneMSecsToEpochMSecs(m_msecs, m_timeZone, &testDate, &testTime); epochMSecs = zoneMSecsToEpochMSecs(m_msecs, m_timeZone, &testDate, &testTime);
@ -3223,7 +3193,7 @@ QString QDateTime::timeZoneAbbreviation() const
case Qt::LocalTime: { case Qt::LocalTime: {
QString abbrev; QString abbrev;
QDateTimePrivate::DaylightStatus status = d->daylightStatus(); QDateTimePrivate::DaylightStatus status = d->daylightStatus();
localMSecsToEpochMSecs(d->m_msecs, 0, 0, &status, &abbrev); localMSecsToEpochMSecs(d->m_msecs, &status, 0, 0, &abbrev);
return abbrev; return abbrev;
} }
} }
@ -3254,7 +3224,7 @@ bool QDateTime::isDaylightTime() const
case Qt::LocalTime: { case Qt::LocalTime: {
QDateTimePrivate::DaylightStatus status = d->daylightStatus(); QDateTimePrivate::DaylightStatus status = d->daylightStatus();
if (status == QDateTimePrivate::UnknownDaylightTime) if (status == QDateTimePrivate::UnknownDaylightTime)
localMSecsToEpochMSecs(d->m_msecs, 0, 0, &status, 0); localMSecsToEpochMSecs(d->m_msecs, &status);
return (status == QDateTimePrivate::DaylightTime); return (status == QDateTimePrivate::DaylightTime);
} }
} }
@ -3469,6 +3439,7 @@ void QDateTime::setMSecsSinceEpoch(qint64 msecs)
epochMSecsToLocalTime(msecs, &dt, &tm, &status); epochMSecsToLocalTime(msecs, &dt, &tm, &status);
d->setDateTime(dt, tm); d->setDateTime(dt, tm);
d->setDaylightStatus(status); d->setDaylightStatus(status);
d->refreshDateTime();
break; break;
} }
} }
@ -3708,12 +3679,14 @@ QDateTime QDateTime::addDays(qint64 ndays) const
date = date.addDays(ndays); date = date.addDays(ndays);
// Result might fall into "missing" DaylightTime transition hour, // Result might fall into "missing" DaylightTime transition hour,
// so call conversion and use the adjusted returned time // so call conversion and use the adjusted returned time
if (d->m_spec == Qt::LocalTime) if (d->m_spec == Qt::LocalTime) {
localMSecsToEpochMSecs(timeToMSecs(date, time), &date, &time); QDateTimePrivate::DaylightStatus status = d->daylightStatus();
localMSecsToEpochMSecs(timeToMSecs(date, time), &status, &date, &time);
#ifndef QT_BOOTSTRAPPED #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); QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(date, time), d->m_timeZone, &date, &time);
#endif // QT_BOOTSTRAPPED #endif // QT_BOOTSTRAPPED
}
dt.d->setDateTime(date, time); dt.d->setDateTime(date, time);
return dt; return dt;
} }
@ -3742,12 +3715,14 @@ QDateTime QDateTime::addMonths(int nmonths) const
date = date.addMonths(nmonths); date = date.addMonths(nmonths);
// Result might fall into "missing" DaylightTime transition hour, // Result might fall into "missing" DaylightTime transition hour,
// so call conversion and use the adjusted returned time // so call conversion and use the adjusted returned time
if (d->m_spec == Qt::LocalTime) if (d->m_spec == Qt::LocalTime) {
localMSecsToEpochMSecs(timeToMSecs(date, time), &date, &time); QDateTimePrivate::DaylightStatus status = d->daylightStatus();
localMSecsToEpochMSecs(timeToMSecs(date, time), &status, &date, &time);
#ifndef QT_BOOTSTRAPPED #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); QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(date, time), d->m_timeZone, &date, &time);
#endif // QT_BOOTSTRAPPED #endif // QT_BOOTSTRAPPED
}
dt.d->setDateTime(date, time); dt.d->setDateTime(date, time);
return dt; return dt;
} }
@ -3776,12 +3751,14 @@ QDateTime QDateTime::addYears(int nyears) const
date = date.addYears(nyears); date = date.addYears(nyears);
// Result might fall into "missing" DaylightTime transition hour, // Result might fall into "missing" DaylightTime transition hour,
// so call conversion and use the adjusted returned time // so call conversion and use the adjusted returned time
if (d->m_spec == Qt::LocalTime) if (d->m_spec == Qt::LocalTime) {
localMSecsToEpochMSecs(timeToMSecs(date, time), &date, &time); QDateTimePrivate::DaylightStatus status = d->daylightStatus();
localMSecsToEpochMSecs(timeToMSecs(date, time), &status, &date, &time);
#ifndef QT_BOOTSTRAPPED #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); QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(date, time), d->m_timeZone, &date, &time);
#endif // QT_BOOTSTRAPPED #endif // QT_BOOTSTRAPPED
}
dt.d->setDateTime(date, time); dt.d->setDateTime(date, time);
return dt; return dt;
} }

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2015 The Qt Company Ltd. ** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2013 Intel Corporation ** Copyright (C) 2015 Intel Corporation
** Contact: http://www.qt.io/licensing/ ** Contact: http://www.qt.io/licensing/
** **
** This file is part of the QtCore module of the Qt Toolkit. ** 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, static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
QLatin1String needle, Qt::CaseSensitivity cs); QLatin1String needle, Qt::CaseSensitivity cs);
#ifdef Q_COMPILER_LAMBDA #if defined(Q_COMPILER_LAMBDA) && !defined(__OPTIMIZE_SIZE__)
namespace { namespace {
template <uint MaxCount> struct UnrollTailLoop template <uint MaxCount> struct UnrollTailLoop
{ {
@ -239,7 +239,7 @@ void qt_from_latin1(ushort *dst, const char *str, size_t size)
size = size % 16; size = size % 16;
dst += offset; dst += offset;
str += 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]; }); return UnrollTailLoop<15>::exec(int(size), [=](int i) { dst[i] = (uchar)str[i]; });
# endif # endif
#endif #endif
@ -332,7 +332,7 @@ static void qt_to_latin1(uchar *dst, const ushort *src, int length)
dst += offset; dst += offset;
src += 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]; }); return UnrollTailLoop<15>::exec(length, [=](int i) { dst[i] = (src[i]>0xff) ? '?' : (uchar) src[i]; });
# endif # endif
#elif defined(__ARM_NEON__) #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(); - 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 { const auto &lambda = [=](int i) -> int {
return reinterpret_cast<const QChar *>(ptr)[i].unicode() return reinterpret_cast<const QChar *>(ptr)[i].unicode()
- reinterpret_cast<const QChar *>(ptr + distance)[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; uc += offset;
c += 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]); }; const auto &lambda = [=](int i) { return uc[i] - ushort(c[i]); };
return UnrollTailLoop<MaxTailLength>::exec(e - uc, 0, lambda, lambda); return UnrollTailLoop<MaxTailLength>::exec(e - uc, 0, lambda, lambda);
# endif # 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, return UnrollTailLoop<7>::exec(e - n, -1,
[=](int i) { return n[i] == c; }, [=](int i) { return n[i] == c; },
[=](int i) { return n - s + i; }); [=](int i) { return n - s + i; });
@ -4797,11 +4797,11 @@ QString QString::trimmed_helper(QString &str)
\overload operator[]() \overload operator[]()
Returns the character at the specified \a position in the string as a 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 /*! \fn const QChar QString::operator[](uint position) const
Equivalent to \c at(position).
\overload operator[]() \overload operator[]()
*/ */

View File

@ -120,21 +120,23 @@ template <typename StringType> struct QStringAlgorithms
Char *dst = const_cast<Char *>(result.cbegin()); Char *dst = const_cast<Char *>(result.cbegin());
Char *ptr = dst; Char *ptr = dst;
bool unmodified = true;
forever { forever {
while (src != end && isSpace(*src)) while (src != end && isSpace(*src))
++src; ++src;
while (src != end && !isSpace(*src)) while (src != end && !isSpace(*src))
*ptr++ = *src++; *ptr++ = *src++;
if (src != end) if (src == end)
*ptr++ = QChar::Space;
else
break; break;
if (*src != QChar::Space)
unmodified = false;
*ptr++ = QChar::Space;
} }
if (ptr != dst && ptr[-1] == QChar::Space) if (ptr != dst && ptr[-1] == QChar::Space)
--ptr; --ptr;
int newlen = ptr - dst; int newlen = ptr - dst;
if (isConst && newlen == str.size()) { if (isConst && newlen == str.size() && unmodified) {
// nothing happened, return the original // nothing happened, return the original
return str; return str;
} }

View File

@ -91,7 +91,7 @@ static inline QString dbusInterfaceString()
static inline QDebug operator<<(QDebug dbg, const QThread *th) 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()) if (th && !th->objectName().isEmpty())
dbg.nospace() << ", name=" << th->objectName(); dbg.nospace() << ", name=" << th->objectName();
else if (th) 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) static inline QDebug operator<<(QDebug dbg, const QDBusConnectionPrivate *conn)
{ {
dbg.nospace() << "QDBusConnection(" dbg.nospace() << "QDBusConnection("
<< "ptr=" << (void*)conn << "ptr=" << (const void*)conn
<< ", name=" << conn->name << ", name=" << conn->name
<< ", baseService=" << conn->baseService << ", baseService=" << conn->baseService
<< ", thread="; << ", thread=";

View File

@ -1718,7 +1718,7 @@ Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAccessibleInterface *iface)
return d; return d;
} }
d.nospace(); d.nospace();
d << "QAccessibleInterface(" << hex << (void *) iface << dec; d << "QAccessibleInterface(" << hex << (const void *) iface << dec;
if (iface->isValid()) { if (iface->isValid()) {
d << " name=" << iface->text(QAccessible::Name) << " "; d << " name=" << iface->text(QAccessible::Name) << " ";
d << "role=" << qAccessibleRoleString(iface->role()) << " "; d << "role=" << qAccessibleRoleString(iface->role()) << " ";

View File

@ -80,6 +80,8 @@ contains(QT_CONFIG, gif):include($$PWD/qgifhandler.pri)
# SIMD # SIMD
SSE2_SOURCES += image/qimage_sse2.cpp SSE2_SOURCES += image/qimage_sse2.cpp
SSSE3_SOURCES += image/qimage_ssse3.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 NEON_SOURCES += image/qimage_neon.cpp
MIPS_DSPR2_SOURCES += image/qimage_mips_dspr2.cpp MIPS_DSPR2_SOURCES += image/qimage_mips_dspr2.cpp
MIPS_DSPR2_ASM += image/qimage_mips_dspr2_asm.S MIPS_DSPR2_ASM += image/qimage_mips_dspr2_asm.S

View File

@ -639,7 +639,7 @@ bool qt_write_dib(QDataStream &s, QImage image)
if (nbits == 1 || nbits == 8) { // direct output if (nbits == 1 || nbits == 8) { // direct output
for (y=image.height()-1; y>=0; y--) { 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 false;
} }
return true; return true;

View File

@ -99,7 +99,7 @@ inline QPixmapIconEngineEntry::QPixmapIconEngineEntry(const QString &file, const
pixmap.setDevicePixelRatio(1.0); pixmap.setDevicePixelRatio(1.0);
} }
class QPixmapIconEngine : public QIconEngine { class Q_GUI_EXPORT QPixmapIconEngine : public QIconEngine {
public: public:
QPixmapIconEngine(); QPixmapIconEngine();
QPixmapIconEngine(const QPixmapIconEngine &); QPixmapIconEngine(const QPixmapIconEngine &);

View File

@ -1433,6 +1433,10 @@ void QImage::setDevicePixelRatio(qreal scaleFactor)
{ {
if (!d) if (!d)
return; return;
if (scaleFactor == d->devicePixelRatio)
return;
detach(); detach();
d->devicePixelRatio = scaleFactor; d->devicePixelRatio = scaleFactor;
} }
@ -2049,7 +2053,7 @@ static QImage convertWithPalette(const QImage &src, QImage::Format format,
if (format == QImage::Format_Indexed8) { if (format == QImage::Format_Indexed8) {
for (int y=0; y<h; ++y) { 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); uchar *dest_pixels = (uchar *) dest.scanLine(y);
for (int x=0; x<w; ++x) { for (int x=0; x<w; ++x) {
int src_pixel = src_pixels[x]; int src_pixel = src_pixels[x];
@ -2065,7 +2069,7 @@ static QImage convertWithPalette(const QImage &src, QImage::Format format,
QVector<QRgb> table = clut; QVector<QRgb> table = clut;
table.resize(2); table.resize(2);
for (int y=0; y<h; ++y) { 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) { for (int x=0; x<w; ++x) {
int src_pixel = src_pixels[x]; int src_pixel = src_pixels[x];
int value = cache.value(src_pixel, -1); int value = cache.value(src_pixel, -1);
@ -2676,7 +2680,7 @@ QImage QImage::createHeuristicMask(bool clipTight) const
return img32.createHeuristicMask(clipTight); 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 w = width();
int h = height(); int h = height();
@ -2710,7 +2714,7 @@ QImage QImage::createHeuristicMask(bool clipTight) const
ypp = ypc; ypp = ypc;
ypc = ypn; ypc = ypn;
ypn = (y == h-1) ? 0 : m.scanLine(y+1); 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++) { for (x = 0; x < w; x++) {
// slowness here - it's possible to do six of these tests // slowness here - it's possible to do six of these tests
// together in one go. oh well. // together in one go. oh well.
@ -2736,7 +2740,7 @@ QImage QImage::createHeuristicMask(bool clipTight) const
ypp = ypc; ypp = ypc;
ypc = ypn; ypc = ypn;
ypn = (y == h-1) ? 0 : m.scanLine(y+1); 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++) { for (x = 0; x < w; x++) {
if ((*p & 0x00ffffff) != background) { if ((*p & 0x00ffffff) != background) {
if (x > 0) if (x > 0)
@ -2780,7 +2784,7 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const
if (depth() == 32) { if (depth() == 32) {
for (int h = 0; h < d->height; h++) { 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++) { for (int w = 0; w < d->width; w++) {
if (sl[w] == color) if (sl[w] == color)
*(s + (w >> 3)) |= (1 << (w & 7)); *(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 case 16: // 16 bpp transform
while (dptr < maxp) { while (dptr < maxp) {
if (trigx < maxws && trigy < maxhs) if (trigx < maxws && trigy < maxhs)
*((ushort*)dptr) = *((ushort *)(sptr+sbpl*(trigy>>12) + *((ushort*)dptr) = *((const ushort *)(sptr+sbpl*(trigy>>12) +
((trigx>>12)<<1))); ((trigx>>12)<<1)));
trigx += m11; trigx += m11;
trigy += m12; trigy += m12;
@ -3899,7 +3903,7 @@ bool qt_xForm_helper(const QTransform &trueMat, int xoffset, int type, int depth
case 32: // 32 bpp transform case 32: // 32 bpp transform
while (dptr < maxp) { while (dptr < maxp) {
if (trigx < maxws && trigy < maxhs) if (trigx < maxws && trigy < maxhs)
*((uint*)dptr) = *((uint *)(sptr+sbpl*(trigy>>12) + *((uint*)dptr) = *((const uint *)(sptr+sbpl*(trigy>>12) +
((trigx>>12)<<2))); ((trigx>>12)<<2)));
trigx += m11; trigx += m11;
trigy += m12; trigy += m12;
@ -4046,7 +4050,7 @@ void QImage::setAlphaChannel(const QImage &alphaChannel)
// Slight optimization since alphachannels are returned as 8-bit grays. // Slight optimization since alphachannels are returned as 8-bit grays.
if (alphaChannel.format() == QImage::Format_Alpha8 ||( alphaChannel.d->depth == 8 && alphaChannel.isGrayscale())) { if (alphaChannel.format() == QImage::Format_Alpha8 ||( alphaChannel.d->depth == 8 && alphaChannel.isGrayscale())) {
const uchar *src_data = alphaChannel.d->data; 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) { for (int y=0; y<h; ++y) {
const uchar *src = src_data; const uchar *src = src_data;
QRgb *dest = (QRgb *)dest_data; QRgb *dest = (QRgb *)dest_data;
@ -4067,7 +4071,7 @@ void QImage::setAlphaChannel(const QImage &alphaChannel)
} else { } else {
const QImage sourceImage = alphaChannel.convertToFormat(QImage::Format_RGB32); const QImage sourceImage = alphaChannel.convertToFormat(QImage::Format_RGB32);
const uchar *src_data = sourceImage.d->data; 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) { for (int y=0; y<h; ++y) {
const QRgb *src = (const QRgb *) src_data; const QRgb *src = (const QRgb *) src_data;
QRgb *dest = (QRgb *) dest_data; QRgb *dest = (QRgb *) dest_data;

View File

@ -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

View File

@ -32,7 +32,6 @@
****************************************************************************/ ****************************************************************************/
#include <private/qdrawhelper_p.h> #include <private/qdrawhelper_p.h>
#include <private/qdrawingprimitive_sse2_p.h>
#include <private/qguiapplication_p.h> #include <private/qguiapplication_p.h>
#include <private/qsimd_p.h> #include <private/qsimd_p.h>
#include <private/qimage_p.h> #include <private/qimage_p.h>
@ -110,17 +109,6 @@ static const uint *QT_FASTCALL convertRGB32FromARGB32PM(uint *buffer, const uint
return buffer; 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, static const uint *QT_FASTCALL convertRGB32ToARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *) const QPixelLayout *, const QRgb *)
{ {
@ -129,6 +117,10 @@ static const uint *QT_FASTCALL convertRGB32ToARGB32PM(uint *buffer, const uint *
return buffer; 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) void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{ {
// Cannot be used with indexed formats. // 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) if (src->format == QImage::Format_RGB32)
convertToARGB32PM = convertRGB32ToARGB32PM; convertToARGB32PM = convertRGB32ToARGB32PM;
if (dest->format == QImage::Format_RGB32) { if (dest->format == QImage::Format_RGB32) {
#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) #ifdef QT_COMPILER_SUPPORTS_SSE4_1
if (qCpuHasFeature(SSE4_1)) if (qCpuHasFeature(SSE4_1))
convertFromARGB32PM = convertRGB32FromARGB32PM_sse4; convertFromARGB32PM = convertRGB32FromARGB32PM_sse4;
else else
@ -201,7 +193,7 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im
if (data->format == QImage::Format_RGB32) if (data->format == QImage::Format_RGB32)
convertToARGB32PM = convertRGB32ToARGB32PM; convertToARGB32PM = convertRGB32ToARGB32PM;
if (dst_format == QImage::Format_RGB32) { if (dst_format == QImage::Format_RGB32) {
#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) #ifdef QT_COMPILER_SUPPORTS_SSE4_1
if (qCpuHasFeature(SSE4_1)) if (qCpuHasFeature(SSE4_1))
convertFromARGB32PM = convertRGB32FromARGB32PM_sse4; convertFromARGB32PM = convertRGB32FromARGB32PM_sse4;
else else
@ -257,7 +249,7 @@ static bool convert_passthrough_inplace(QImageData *data, Qt::ImageConversionFla
return true; 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(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(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) Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32(quint32 *dest_data, const uchar *src_data, int len)
{ {
int pixel = 0; 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. // Handle 4 pixels at a time 12 bytes input to 16 bytes output.
for (; pixel + 3 < len; pixel += 4) { 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 src1 = qFromBigEndian(src_packed[0]);
const quint32 src2 = qFromBigEndian(src_packed[1]); const quint32 src2 = qFromBigEndian(src_packed[1]);
const quint32 src3 = qFromBigEndian(src_packed[2]); 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. // Handle 4 pixels at a time 12 bytes input to 16 bytes output.
for (; pixel + 3 < len; pixel += 4) { 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 src1 = src_packed[0];
const quint32 src2 = src_packed[1]; const quint32 src2 = src_packed[1];
const quint32 src3 = src_packed[2]; const quint32 src3 = src_packed[2];
@ -1109,12 +1092,12 @@ void dither_to_Mono(QImageData *dst, const QImageData *src,
} else { // 32 bit image } else { // 32 bit image
if (fromalpha) { if (fromalpha) {
while (p < end) { while (p < end) {
*b2++ = 255 - (*(uint*)p >> 24); *b2++ = 255 - (*(const uint*)p >> 24);
p += 4; p += 4;
} }
} else { } else {
while (p < end) { while (p < end) {
*b2++ = qGray(*(uint*)p); *b2++ = qGray(*(const uint*)p);
p += 4; p += 4;
} }
} }
@ -1132,12 +1115,12 @@ void dither_to_Mono(QImageData *dst, const QImageData *src,
} else { // 24 bit image } else { // 24 bit image
if (fromalpha) { if (fromalpha) {
while (p < end) { while (p < end) {
*b2++ = 255 - (*(uint*)p >> 24); *b2++ = 255 - (*(const uint*)p >> 24);
p += 4; p += 4;
} }
} else { } else {
while (p < end) { while (p < end) {
*b2++ = qGray(*(uint*)p); *b2++ = qGray(*(const uint*)p);
p += 4; p += 4;
} }
} }
@ -2804,13 +2787,22 @@ void qInitImageConversions()
} }
#endif #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)) { 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_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; qimage_converter_map[QImage::Format_RGBA8888][QImage::Format_RGBA8888_Premultiplied] = convert_ARGB_to_ARGB_PM_sse4;
} }
#endif #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) #if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); 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; qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon;

View File

@ -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

View File

@ -65,7 +65,7 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, con
// Mask to have alpha = 0xff // Mask to have alpha = 0xff
const __m128i alphaMask = _mm_set1_epi32(0xff000000); const __m128i alphaMask = _mm_set1_epi32(0xff000000);
__m128i *inVectorPtr = (__m128i *)src; const __m128i *inVectorPtr = (const __m128i *)src;
__m128i *dstVectorPtr = (__m128i *)dst; __m128i *dstVectorPtr = (__m128i *)dst;
const int simdRoundCount = (len - prologLength) / 16; // one iteration in the loop converts 16 pixels 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)); _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask));
++dstVectorPtr; ++dstVectorPtr;
} }
src = (uchar *)inVectorPtr; src = (const uchar *)inVectorPtr;
dst = (quint32 *)dstVectorPtr; dst = (quint32 *)dstVectorPtr;
while (dst != end) { while (dst != end) {

View File

@ -514,7 +514,7 @@ static inline void set_text(const QImage &image, j_compress_ptr cinfo, const QSt
comment += it.value().toLatin1(); comment += it.value().toLatin1();
if (comment.length() > 65530) if (comment.length() > 65530)
comment.truncate(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());
} }
} }

View File

@ -1362,7 +1362,7 @@ void QPictureIO::init()
QPictureIO::~QPictureIO() QPictureIO::~QPictureIO()
{ {
if (d->parameters) if (d->parameters)
delete [] (char*)d->parameters; delete [] d->parameters;
delete d; delete d;
} }
@ -1671,7 +1671,7 @@ const char *QPictureIO::parameters() const
void QPictureIO::setParameters(const char *parameters) void QPictureIO::setParameters(const char *parameters)
{ {
if (d->parameters) if (d->parameters)
delete [] (char*)d->parameters; delete [] d->parameters;
d->parameters = qstrdup(parameters); d->parameters = qstrdup(parameters);
} }

View File

@ -682,6 +682,9 @@ void QPixmap::setDevicePixelRatio(qreal scaleFactor)
if (isNull()) if (isNull())
return; return;
if (scaleFactor == data->devicePixelRatio())
return;
detach(); detach();
data->setDevicePixelRatio(scaleFactor); data->setDevicePixelRatio(scaleFactor);
} }

View File

@ -942,7 +942,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, vo
// 0123456789aBC // 0123456789aBC
data[0xB] = looping%0x100; data[0xB] = looping%0x100;
data[0xC] = 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) { if (ms_delay >= 0 || disposal!=Unspecified) {
uchar data[4]; uchar data[4];
@ -950,7 +950,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, vo
data[1] = 0; data[1] = 0;
data[2] = (ms_delay/10)/0x100; // hundredths data[2] = (ms_delay/10)/0x100; // hundredths
data[3] = (ms_delay/10)%0x100; 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(); 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]; png_bytep* row_pointers = new png_bytep[height];
for (int y=0; y<height; y++) 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); png_write_image(png_ptr, row_pointers);
delete [] 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]; png_bytep row_pointers[1];
for (int y=0; y<height; y++) { for (int y=0; y<height; y++) {
row = image.copy(0, y, width, 1).convertToFormat(fmt); 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); png_write_rows(png_ptr, row_pointers, 1);
} }
} }

View File

@ -33,8 +33,6 @@
#include "qcursor.h" #include "qcursor.h"
#ifndef QT_NO_CURSOR
#include <qcoreapplication.h> #include <qcoreapplication.h>
#include <qbitmap.h> #include <qbitmap.h>
#include <qimage.h> #include <qimage.h>
@ -259,6 +257,8 @@ void QCursor::setPos(int x, int y)
QCursor::setPos(QGuiApplication::primaryScreen(), x, y); QCursor::setPos(QGuiApplication::primaryScreen(), x, y);
} }
#ifndef QT_NO_CURSOR
/*! /*!
\fn void QCursor::setPos (const QPoint &p) \fn void QCursor::setPos (const QPoint &p)

View File

@ -147,12 +147,15 @@ QString *QGuiApplicationPrivate::displayName = 0;
QPalette *QGuiApplicationPrivate::app_pal = 0; // default application palette QPalette *QGuiApplicationPrivate::app_pal = 0; // default application palette
Qt::MouseButtons QGuiApplicationPrivate::buttons = Qt::NoButton; Qt::MouseButtons QGuiApplicationPrivate::buttons = Qt::NoButton;
ulong QGuiApplicationPrivate::mousePressTime = 0; ulong QGuiApplicationPrivate::mousePressTime = 0;
Qt::MouseButton QGuiApplicationPrivate::mousePressButton = Qt::NoButton; Qt::MouseButton QGuiApplicationPrivate::mousePressButton = Qt::NoButton;
int QGuiApplicationPrivate::mousePressX = 0; int QGuiApplicationPrivate::mousePressX = 0;
int QGuiApplicationPrivate::mousePressY = 0; int QGuiApplicationPrivate::mousePressY = 0;
int QGuiApplicationPrivate::mouse_double_click_distance = -1; int QGuiApplicationPrivate::mouse_double_click_distance = -1;
QWindow *QGuiApplicationPrivate::currentMousePressWindow = 0;
static Qt::LayoutDirection layout_direction = Qt::LeftToRight; static Qt::LayoutDirection layout_direction = Qt::LeftToRight;
static bool force_reverse = false; static bool force_reverse = false;
@ -1703,6 +1706,17 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
if (e->nullWindow()) { if (e->nullWindow()) {
window = QGuiApplication::topLevelAt(globalPoint.toPoint()); window = QGuiApplication::topLevelAt(globalPoint.toPoint());
if (window) { 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(); QPointF delta = globalPoint - globalPoint.toPoint();
localPoint = window->mapFromGlobal(globalPoint.toPoint()) + delta; localPoint = window->mapFromGlobal(globalPoint.toPoint()) + delta;
} }
@ -2554,7 +2568,7 @@ void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate:
} }
if (availableGeometryChanged) if (availableGeometryChanged)
emit s->availableGeometryChanged(s->geometry()); emit s->availableGeometryChanged(s->availableGeometry());
if (geometryChanged || availableGeometryChanged) { if (geometryChanged || availableGeometryChanged) {
foreach (QScreen* sibling, s->virtualSiblings()) foreach (QScreen* sibling, s->virtualSiblings())

View File

@ -200,6 +200,7 @@ public:
static Qt::MouseButtons tabletState; static Qt::MouseButtons tabletState;
static QWindow *tabletPressTarget; static QWindow *tabletPressTarget;
static QWindow *currentMouseWindow; static QWindow *currentMouseWindow;
static QWindow *currentMousePressWindow;
static Qt::ApplicationState applicationState; static Qt::ApplicationState applicationState;
#ifndef QT_NO_CLIPBOARD #ifndef QT_NO_CLIPBOARD

View File

@ -36,6 +36,25 @@
QT_BEGIN_NAMESPACE 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) QInputDeviceManager::QInputDeviceManager(QObject *parent)
: QObject(*new QInputDeviceManagerPrivate, 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 QT_END_NAMESPACE

View File

@ -68,8 +68,11 @@ public:
int deviceCount(DeviceType type) const; int deviceCount(DeviceType type) const;
void setCursorPos(const QPoint &pos);
signals: signals:
void deviceListChanged(DeviceType type); void deviceListChanged(DeviceType type);
void cursorPositionChangeRequested(const QPoint &pos);
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -112,6 +112,7 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe
bool *swizzleRandB, bool *swizzleRandB,
const QRect &subRect) const QRect &subRect)
{ {
#ifndef QT_NO_OPENGL
if (!QOpenGLContext::currentContext()) if (!QOpenGLContext::currentContext())
return false; return false;
@ -172,6 +173,12 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe
return true; return true;
#else
Q_UNUSED(graphicsBuffer)
Q_UNUSED(swizzleRandB)
Q_UNUSED(subRect)
return false;
#endif // QT_NO_OPENGL
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -103,6 +103,7 @@ public:
virtual void setText(const QString &text) = 0; virtual void setText(const QString &text) = 0;
virtual void setIcon(const QIcon &icon) = 0; virtual void setIcon(const QIcon &icon) = 0;
virtual void setEnabled(bool enabled) = 0; virtual void setEnabled(bool enabled) = 0;
virtual bool isEnabled() const { return true; }
virtual void setVisible(bool visible) = 0; virtual void setVisible(bool visible) = 0;
virtual void setMinimumWidth(int width) { Q_UNUSED(width); } virtual void setMinimumWidth(int width) { Q_UNUSED(width); }
virtual void setFont(const QFont &font) { Q_UNUSED(font); } virtual void setFont(const QFont &font) { Q_UNUSED(font); }

View File

@ -1599,6 +1599,8 @@ void QWindow::destroy()
QGuiApplicationPrivate::focus_window = parent(); QGuiApplicationPrivate::focus_window = parent();
if (QGuiApplicationPrivate::currentMouseWindow == this) if (QGuiApplicationPrivate::currentMouseWindow == this)
QGuiApplicationPrivate::currentMouseWindow = parent(); QGuiApplicationPrivate::currentMouseWindow = parent();
if (QGuiApplicationPrivate::currentMousePressWindow == this)
QGuiApplicationPrivate::currentMousePressWindow = parent();
if (QGuiApplicationPrivate::tabletPressTarget == this) if (QGuiApplicationPrivate::tabletPressTarget == this)
QGuiApplicationPrivate::tabletPressTarget = parent(); QGuiApplicationPrivate::tabletPressTarget = parent();

View File

@ -77,6 +77,9 @@ public:
struct Gpu { struct Gpu {
Gpu() : vendorId(0), deviceId(0) {} Gpu() : vendorId(0), deviceId(0) {}
bool isValid() const { return deviceId; } bool isValid() const { return deviceId; }
bool equals(const Gpu &other) const {
return vendorId == other.vendorId && deviceId == other.deviceId && driverVersion == other.driverVersion;
}
uint vendorId; uint vendorId;
uint deviceId; uint deviceId;
@ -93,6 +96,21 @@ public:
static QSet<QString> gpuFeatures(const Gpu &gpu, const QString &fileName); 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 QT_END_NAMESPACE
#endif // QOPENGL_H #endif // QOPENGL_H

View File

@ -1229,7 +1229,7 @@ void QOpenGL2PaintEngineExPrivate::drawVertexArrays(const float *data, int *stop
GLenum primitive) GLenum primitive)
{ {
// Now setup the pointer to the vertex array: // Now setup the pointer to the vertex array:
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)data); setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, data);
int previousStop = 0; int previousStop = 0;
for (int i=0; i<stopCount; ++i) { for (int i=0; i<stopCount; ++i) {

View File

@ -40,8 +40,16 @@ QT_BEGIN_NAMESPACE
QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context) QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
{ {
// Resolve EXT_direct_state_access entry points if present // Resolve EXT_direct_state_access entry points if present.
if (!context->isOpenGLES()
// 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"))) { && context->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) {
TextureParameteriEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , GLint )>(context->getProcAddress(QByteArrayLiteral("glTextureParameteriEXT"))); 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"))); TextureParameterivEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , const GLint *)>(context->getProcAddress(QByteArrayLiteral("glTextureParameterivEXT")));

View File

@ -94,6 +94,8 @@ SOURCES += \
SSE2_SOURCES += painting/qdrawhelper_sse2.cpp SSE2_SOURCES += painting/qdrawhelper_sse2.cpp
SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp
AVX2_SOURCES += painting/qdrawhelper_avx2.cpp
!ios { !ios {
CONFIG += no_clang_integrated_as CONFIG += no_clang_integrated_as

View File

@ -245,7 +245,7 @@ static void qt_blend_argb32_on_rgb16(uchar *destPixels, int dbpl,
} }
quint16 *dst = (quint16 *) destPixels; quint16 *dst = (quint16 *) destPixels;
quint32 *src = (quint32 *) srcPixels; const quint32 *src = (const quint32 *) srcPixels;
for (int y=0; y<h; ++y) { for (int y=0; y<h; ++y) {
for (int x=0; x<w; ++x) { 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); dst = (quint16 *) (((uchar *) dst) + dbpl);
src = (quint32 *) (((uchar *) src) + sbpl); src = (const quint32 *) (((const uchar *) src) + sbpl);
} }
} }

View File

@ -437,8 +437,9 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal
int y = (y1 + 32) >> 6; int y = (y1 + 32) >> 6;
int ys = (y2 + 32) >> 6; int ys = (y2 + 32) >> 6;
int round = (xinc > 0) ? 32 : 0;
if (y != ys) { if (y != ys) {
x += ( ((((y << 6) + 32 - y1))) * xinc ) >> 6; x += ( ((((y << 6) + round - y1))) * xinc ) >> 6;
if (swapped) { if (swapped) {
lastPixel.x = x >> 16; lastPixel.x = x >> 16;
@ -468,8 +469,9 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal
int x = (x1 + 32) >> 6; int x = (x1 + 32) >> 6;
int xs = (x2 + 32) >> 6; int xs = (x2 + 32) >> 6;
int round = (yinc > 0) ? 32 : 0;
if (x != xs) { if (x != xs) {
y += ( ((((x << 6) + 32 - x1))) * yinc ) >> 6; y += ( ((((x << 6) + round - x1))) * yinc ) >> 6;
if (swapped) { if (swapped) {
lastPixel.x = x; lastPixel.x = x;
@ -762,9 +764,10 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
int y = (y1 + 32) >> 6; int y = (y1 + 32) >> 6;
int ys = (y2 + 32) >> 6; int ys = (y2 + 32) >> 6;
int round = (xinc > 0) ? 32 : 0;
if (y != ys) { 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 // calculate first and last pixel and perform dropout control
QCosmeticStroker::Point first; QCosmeticStroker::Point first;
@ -837,9 +840,10 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
int x = (x1 + 32) >> 6; int x = (x1 + 32) >> 6;
int xs = (x2 + 32) >> 6; int xs = (x2 + 32) >> 6;
int round = (yinc > 0) ? 32 : 0;
if (x != xs) { 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 // calculate first and last pixel to perform dropout control
QCosmeticStroker::Point first; QCosmeticStroker::Point first;

View File

@ -355,25 +355,12 @@ static const uint *QT_FASTCALL convertPassThrough(uint *, const uint *src, int,
return src; return src;
} }
static inline const uint *QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count, static const uint *QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *) const QPixelLayout *, const QRgb *)
{ {
for (int i = 0; i < count; ++i) return qt_convertARGB32ToARGB32PM(buffer, src, count);
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)
{
// Twice as fast autovectorized due to SSE4.1 PMULLD instructions.
return convertARGB32ToARGB32PM(buffer, src, count, layout, clut);
}
#endif
static const uint *QT_FASTCALL convertRGBA8888PMToARGB32PM(uint *buffer, const uint *src, int count, static const uint *QT_FASTCALL convertRGBA8888PMToARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *) const QPixelLayout *, const QRgb *)
{ {
@ -382,24 +369,12 @@ static const uint *QT_FASTCALL convertRGBA8888PMToARGB32PM(uint *buffer, const u
return buffer; 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 *) const QPixelLayout *, const QRgb *)
{ {
for (int i = 0; i < count; ++i) return qt_convertRGBA8888ToARGB32PM(buffer, src, count);
buffer[i] = qPremultiply(RGBA2ARGB(src[i]));
return buffer;
} }
#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, static const uint *QT_FASTCALL convertAlpha8ToRGB32(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *) const QPixelLayout *, const QRgb *)
{ {
@ -424,18 +399,6 @@ static const uint *QT_FASTCALL convertARGB32FromARGB32PM(uint *buffer, const uin
return buffer; 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, static const uint *QT_FASTCALL convertRGBA8888PMFromARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *) const QPixelLayout *, const QRgb *)
{ {
@ -452,17 +415,6 @@ static const uint *QT_FASTCALL convertRGBA8888FromARGB32PM(uint *buffer, const u
return buffer; 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, static const uint *QT_FASTCALL convertRGBXFromRGB32(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *) const QPixelLayout *, const QRgb *)
{ {
@ -479,17 +431,6 @@ static const uint *QT_FASTCALL convertRGBXFromARGB32PM(uint *buffer, const uint
return buffer; 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> template<QtPixelOrder PixelOrder>
static const uint *QT_FASTCALL convertA2RGB30PMToARGB32PM(uint *buffer, const uint *src, int count, static const uint *QT_FASTCALL convertA2RGB30PMToARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *) const QPixelLayout *, const QRgb *)
@ -1454,7 +1395,7 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
lim -= 3; lim -= 3;
for (; f < lim; x += 4, f += 4) { for (; f < lim; x += 4, f += 4) {
// Load 4 pixels from s1, and split the alpha-green and red-blue component // 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 topAG = _mm_srli_epi16(top, 8);
__m128i topRB = _mm_and_si128(top, colorMask); __m128i topRB = _mm_and_si128(top, colorMask);
// Multiplies each colour component by idisty // 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_); topRB = _mm_mullo_epi16 (topRB, idisty_);
// Same for the s2 vector // 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 bottomAG = _mm_srli_epi16(bottom, 8);
__m128i bottomRB = _mm_and_si128(bottom, colorMask); __m128i bottomRB = _mm_and_si128(bottom, colorMask);
bottomAG = _mm_mullo_epi16 (bottomAG, disty_); 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; length = image_width - sx;
if (length > 0) { if (length > 0) {
const int coverage = (spans->coverage * data->texture.const_alpha) >> 8; 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; uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x;
op.func(dest, src, length, coverage); 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; length = image_width - sx;
if (length > 0) { if (length > 0) {
quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + x; 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) { if (coverage == 255) {
memcpy(dest, src, length * sizeof(quint16)); memcpy(dest, src, length * sizeof(quint16));
} else { } else {
@ -4939,7 +4880,7 @@ static void blend_tiled_argb(int count, const QSpan *spans, void *userData)
int l = qMin(image_width - sx, length); int l = qMin(image_width - sx, length);
if (buffer_size < l) if (buffer_size < l)
l = buffer_size; 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; uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x;
op.func(dest, src, l, coverage); op.func(dest, src, l, coverage);
x += l; x += l;
@ -4998,7 +4939,7 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData)
if (buffer_size < l) if (buffer_size < l)
l = buffer_size; l = buffer_size;
quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans->y)) + tx; 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)); memcpy(dest, src, l * sizeof(quint16));
length -= l; length -= l;
tx += l; tx += l;
@ -5032,7 +4973,7 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData)
if (buffer_size < l) if (buffer_size < l)
l = buffer_size; l = buffer_size;
quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans->y)) + x; 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); blend_sourceOver_rgb16_rgb16(dest, src, l, alpha, ialpha);
x += l; x += l;
length -= 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_minx, src_maxx, x1, x2);
fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_miny, src_maxy, y1, y2); fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_miny, src_maxy, y1, y2);
const quint16 *src1 = (quint16*)data->texture.scanLine(y1); const quint16 *src1 = (const quint16*)data->texture.scanLine(y1);
const quint16 *src2 = (quint16*)data->texture.scanLine(y2); const quint16 *src2 = (const quint16*)data->texture.scanLine(y2);
quint16 tl = src1[x1]; quint16 tl = src1[x1];
const quint16 tr = src1[x2]; const quint16 tr = src1[x2];
quint16 bl = src2[x1]; 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_minx, src_maxx, x1, x2);
fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_miny, src_maxy, y1, y2); fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_miny, src_maxy, y1, y2);
const quint16 *src1 = (quint16 *)data->texture.scanLine(y1); const quint16 *src1 = (const quint16 *)data->texture.scanLine(y1);
const quint16 *src2 = (quint16 *)data->texture.scanLine(y2); const quint16 *src2 = (const quint16 *)data->texture.scanLine(y2);
quint16 tl = src1[x1]; quint16 tl = src1[x1];
const quint16 tr = src1[x2]; const quint16 tr = src1[x2];
quint16 bl = src2[x1]; 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 px = qBound(0, x >> 16, image_width - 1);
const int py = qBound(0, y >> 16, image_height - 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; ++b;
x += fdx; 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 px = qBound(0, int(tx) - (tx < 0), image_width - 1);
const int py = qBound(0, int(ty) - (ty < 0), image_height - 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; ++b;
x += fdx; 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); void *t = data->rasterBuffer->scanLine(spans->y);
uint *target = ((uint *)t) + spans->x; 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 cx = spans->x + qreal(0.5);
const qreal cy = spans->y + 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); void *t = data->rasterBuffer->scanLine(spans->y);
uint *target = ((uint *)t) + spans->x; 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 cx = spans->x + qreal(0.5);
const qreal cy = spans->y + 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) if (py < 0)
py += image_height; py += image_height;
*b = ((quint16 *)data->texture.scanLine(py))[px]; *b = ((const quint16 *)data->texture.scanLine(py))[px];
++b; ++b;
x += fdx; x += fdx;
@ -5727,7 +5668,7 @@ static void blend_transformed_tiled_rgb565(int count, const QSpan *spans, void *
if (py < 0) if (py < 0)
py += image_height; py += image_height;
*b = ((quint16 *)data->texture.scanLine(py))[px]; *b = ((const quint16 *)data->texture.scanLine(py))[px];
++b; ++b;
x += fdx; x += fdx;
@ -6793,18 +6734,32 @@ void qInitDrawhelperAsm()
} }
#endif // SSSE3 #endif // SSSE3
#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) #if QT_COMPILER_SUPPORTS_SSE4_1
if (qCpuHasFeature(SSE4_1)) { if (qCpuHasFeature(SSE4_1)) {
#if !defined(__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_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_sse4;
qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_sse4;
#endif #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_ARGB32].convertFromARGB32PM = convertARGB32FromARGB32PM_sse4;
qPixelLayouts[QImage::Format_RGBA8888].convertFromARGB32PM = convertRGBA8888FromARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBA8888].convertFromARGB32PM = convertRGBA8888FromARGB32PM_sse4;
qPixelLayouts[QImage::Format_RGBX8888].convertFromARGB32PM = convertRGBXFromARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBX8888].convertFromARGB32PM = convertRGBXFromARGB32PM_sse4;
} }
#endif #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; functionForModeAsm = qt_functionForMode_SSE2;
functionForModeSolidAsm = qt_functionForModeSolid_SSE2; functionForModeSolidAsm = qt_functionForModeSolid_SSE2;
#endif // SSE2 #endif // SSE2

View File

@ -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

View File

@ -769,7 +769,7 @@ do { \
do { \ do { \
/* Duff's device */ \ /* Duff's device */ \
ushort *_d = (ushort*)(dest); \ ushort *_d = (ushort*)(dest); \
const ushort *_s = (ushort*)(src); \ const ushort *_s = (const ushort*)(src); \
int n = ((length) + 7) / 8; \ int n = ((length) + 7) / 8; \
switch ((length) & 0x07) \ switch ((length) & 0x07) \
{ \ { \
@ -893,6 +893,22 @@ inline int qBlue565(quint16 rgb) {
return (b << 3) | (b >> 2); 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] = { const uint qt_bayer_matrix[16][16] = {
{ 0x1, 0xc0, 0x30, 0xf0, 0xc, 0xcc, 0x3c, 0xfc, { 0x1, 0xc0, 0x30, 0xf0, 0xc, 0xcc, 0x3c, 0xfc,
0x3, 0xc3, 0x33, 0xf3, 0xf, 0xcf, 0x3f, 0xff}, 0x3, 0xc3, 0x33, 0xf3, 0xf, 0xcf, 0x3f, 0xff},

Some files were not shown because too many files have changed in this diff Show More