Merge "Merge remote-tracking branch 'origin/5.8' into dev" into refs/staging/dev

This commit is contained in:
Liang Qi 2016-09-21 15:56:19 +00:00 committed by The Qt Project
commit abbc5ecc5e
105 changed files with 1793 additions and 1644 deletions

View File

@ -200,9 +200,11 @@ sub shouldMasterInclude {
}
######################################################################
# Syntax: classNames(iheader, clean)
# Syntax: classNames(iheader, clean, requires)
# Params: iheader, string, filename to parse for classname "symlinks"
# (out) clean, boolean, will be set to false if the header isn't clean
# (out) requires, string, will be set to non-empty if the header
# requires a feature
#
# Purpose: Scans through iheader to find all classnames that should be
# synced into library's include structure.
@ -210,8 +212,9 @@ sub shouldMasterInclude {
######################################################################
sub classNames {
my @ret;
my ($iheader, $clean) = @_;
my ($iheader, $clean, $requires) = @_;
$$clean = 1;
$$requires = "";
my $ihdrbase = basename($iheader);
my $classname = $classnames{$ihdrbase};
@ -236,6 +239,7 @@ sub classNames {
$line .= ";" if($line =~ m/^QT_(BEGIN|END)_NAMESPACE(_[A-Z]+)*[\r\n]*$/); #qt macro
$line .= ";" if($line =~ m/^QT_MODULE\(.*\)[\r\n]*$/); # QT_MODULE macro
$line .= ";" if($line =~ m/^QT_WARNING_(PUSH|POP|DISABLE_\w+\(.*\))[\r\n]*$/); # qt macros
$$requires = $1 if ($line =~ m/^QT_REQUIRE_CONFIG\((.*)\);[\r\n]*$/);
$parsable .= " " . $line;
}
}
@ -706,6 +710,21 @@ sub isQpaHeader
return 0;
}
sub globosort($$) {
my ($a, $b) = @_;
if ($a =~ /^q(.*)global\.h$/) {
my $sa = $1;
if ($b =~ /^q(.*)global\.h$/) {
my $sb = $1;
# Compare stems so qglobal.h (empty stem) is first:
return $sa cmp $sb;
}
return -1; # $a is global, so before $b
}
return +1 if $b =~ /^q.*global\.h$/; # $a not global, so after $b
return $a cmp $b;
}
# check if this is an in-source build, and if so use that as the basedir too
$basedir = locateSyncProfile($out_basedir);
if ($basedir) {
@ -914,10 +933,7 @@ foreach my $lib (@modules_to_sync) {
my $pri_clean_files = "";
my $libcapitals = uc($lib);
my $master_contents =
"#ifndef QT_".$libcapitals."_MODULE_H\n" .
"#define QT_".$libcapitals."_MODULE_H\n" .
"#include <$lib/${lib}Depends>\n";
my %master_contents = ();
#remove the old files
if($remove_stale) {
@ -1017,6 +1033,7 @@ foreach my $lib (@modules_to_sync) {
}
my $clean_header;
my $requires;
my $iheader = $subdir . "/" . $header;
$iheader =~ s/^\Q$basedir\E/$out_basedir/ if ($shadow);
if ($check_includes) {
@ -1025,7 +1042,7 @@ foreach my $lib (@modules_to_sync) {
&& $header =~ /_p\.h$/ && $subdir !~ /3rdparty/;
check_header($lib, $header, $iheader, $public_header, $private_header);
}
my @classes = $public_header && (!$minimal && $is_qt) ? classNames($iheader, \$clean_header) : ();
my @classes = $public_header && (!$minimal && $is_qt) ? classNames($iheader, \$clean_header, \$requires) : ();
if($showonly) {
print "$header [$lib]\n";
foreach(@classes) {
@ -1059,7 +1076,7 @@ foreach my $lib (@modules_to_sync) {
my $injection = "";
if($public_header) {
#put it into the master file
$master_contents .= "#include \"$public_header\"\n" if (!$shadow && shouldMasterInclude($iheader));
$master_contents{$public_header} = $requires if (!$shadow && shouldMasterInclude($iheader));
#deal with the install directives
foreach my $class (@classes) {
@ -1074,7 +1091,7 @@ foreach my $lib (@modules_to_sync) {
$injection .= ":$class";
}
$pri_install_files.= "$pri_install_iheader ";;
$pri_clean_files .= "$pri_install_iheader " if ($clean_header);
$pri_clean_files .= "$pri_install_iheader".($requires ? ":".$requires : "")." " if ($clean_header);
}
elsif ($qpa_header) {
$pri_install_qpafiles.= "$pri_install_iheader ";;
@ -1113,8 +1130,17 @@ foreach my $lib (@modules_to_sync) {
}
}
# close the master include:
$master_contents .=
# populate the master include:
my $master_contents =
"#ifndef QT_".$libcapitals."_MODULE_H\n" .
"#define QT_".$libcapitals."_MODULE_H\n" .
"#include <$lib/${lib}Depends>\n" .
join("", map {
my $rq = $master_contents{$_};
($rq ? "#if QT_CONFIG($rq)\n" : "") .
"#include \"$_\"\n" .
($rq ? "#endif\n" : "")
} sort globosort keys %master_contents) .
"#include \"".lc($lib)."version.h\"\n" .
"#endif\n";

View File

@ -243,16 +243,23 @@ headersclean:!internal_module {
}
!isEmpty(hcleanCOMMAND):if(!qtConfig(debug_and_release)|CONFIG(release, debug|release)) {
CLEAN_HEADERS =
for (h, SYNCQT.CLEAN_HEADER_FILES) {
hh = $$split(h, :)
hr = $$member(hh, 1)
isEmpty(hr)|qtConfig($$hr): \
CLEAN_HEADERS += $$member(hh, 0)
}
CLEAN_HEADERS -= $$HEADERSCLEAN_EXCLUDE
header_check.dependency_type = TYPE_C
header_check.CONFIG += no_link
header_check.output = ${QMAKE_VAR_OBJECTS_DIR}header_${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
header_check.input = SYNCQT.CLEAN_HEADER_FILES
header_check.input = CLEAN_HEADERS
header_check.variable_out = PRE_TARGETDEPS
header_check.name = headercheck ${QMAKE_FILE_IN}
header_check.commands = $$hcleanCOMMAND
silent:header_check.commands = @echo compiling[header] ${QMAKE_FILE_IN} && $$hcleanCOMMAND
QMAKE_EXTRA_COMPILERS += header_check
SYNCQT.CLEAN_HEADER_FILES -= $$HEADERSCLEAN_EXCLUDE
}
unset(hcleanCOMMAND)
unset(hcleanFLAGS)

View File

@ -69,7 +69,7 @@ DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB
include(../zlib_dependency.pri)
QT_FOR_CONFIG += gui-private
include(../../gui/qtgui-config.pri)
include($$OUT_PWD/../../gui/qtgui-config.pri)
DEFINES += FT_CONFIG_OPTION_USE_PNG
include($$PWD/../png_dependency.pri)

View File

@ -1455,4 +1455,9 @@ public class QtActivityDelegate
}
return false;
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
{
QtNative.sendRequestPermissionsResult(requestCode, permissions, grantResults);
}
}

View File

@ -455,20 +455,25 @@ public class QtNative
}
}
public static int checkSelfPermission(final String permission)
public static Context getContext() {
if (m_activity != null)
return m_activity;
return m_service;
}
public static int checkSelfPermission(String permission)
{
int perm = PackageManager.PERMISSION_DENIED;
synchronized (m_mainActivityMutex) {
if (m_activity == null)
return perm;
Context context = getContext();
try {
if (Build.VERSION.SDK_INT >= 23) {
if (m_checkSelfPermissionMethod == null)
m_checkSelfPermissionMethod = Context.class.getMethod("checkSelfPermission", String.class);
perm = (Integer)m_checkSelfPermissionMethod.invoke(m_activity, permission);
perm = (Integer)m_checkSelfPermissionMethod.invoke(context, permission);
} else {
final PackageManager pm = m_activity.getPackageManager();
perm = pm.checkPermission(permission, m_activity.getPackageName());
final PackageManager pm = context.getPackageManager();
perm = pm.checkPermission(permission, context.getApplicationContext().getPackageName());
}
} catch (Exception e) {
e.printStackTrace();
@ -831,6 +836,8 @@ public class QtNative
public static native void runPendingCppRunnables();
public static native void sendRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults);
private static native void setNativeActivity(Activity activity);
private static native void setNativeService(Service service);
}

View File

@ -981,4 +981,11 @@ public class QtActivity extends Activity
//---------------------------------------------------------------------------
//@ANDROID-12
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
{
if (QtApplication.m_delegateObject != null && QtApplication.onRequestPermissionsResult != null) {
QtApplication.invokeDelegateMethod(QtApplication.onRequestPermissionsResult, requestCode , permissions, grantResults);
return;
}
}
}

View File

@ -64,6 +64,7 @@ public class QtApplication extends Application
public static Method onKeyShortcut = null;
public static Method dispatchGenericMotionEvent = null;
public static Method onGenericMotionEvent = null;
public static Method onRequestPermissionsResult = null;
private static String activityClassName;
public static void setQtContextDelegate(Class<?> clazz, Object listener)
{

View File

@ -1,5 +1,5 @@
CONFIG += static
include(../../../../gui/qtgui-config.pri)
include($$OUT_PWD/../../../../gui/qtgui-config.pri)
qtConfig(dynamicgl): CONFIG += not_installed
include(../../config.pri)

View File

@ -1,5 +1,5 @@
CONFIG += static
include(../../../gui/qtgui-config.pri)
include($$OUT_PWD/../../../gui/qtgui-config.pri)
qtConfig(dynamicgl): CONFIG += not_installed
include(../config.pri)

View File

@ -37,8 +37,4 @@ HEADERS += \
# private headers
HEADERS += \
qtConfig(clock-gettime) {
linux-*|hpux-*|solaris-*: LIBS_PRIVATE *= -lrt
}
load(qt_module)

View File

@ -39,20 +39,7 @@
#include "qtconcurrentiteratekernel.h"
#if defined(Q_OS_MAC)
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <unistd.h>
#elif defined(Q_OS_UNIX)
#if defined(Q_OS_HURD)
#include <sys/time.h>
#endif
#include <time.h>
#include <unistd.h>
#elif defined(Q_OS_WIN)
#include <qt_windows.h>
#endif
#include <qdeadlinetimer.h>
#include "private/qfunctions_p.h"
@ -65,69 +52,11 @@ enum {
MedianSize = 7
};
#if defined(Q_OS_MAC)
static qint64 getticks()
{
return mach_absolute_time();
return QDeadlineTimer::current(Qt::PreciseTimer).deadlineNSecs();
}
#elif defined(Q_OS_UNIX)
static qint64 getticks()
{
#if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)) || defined(Q_OS_OPENBSD)
clockid_t clockId;
#ifndef _POSIX_THREAD_CPUTIME
clockId = CLOCK_REALTIME;
#elif (_POSIX_THREAD_CPUTIME-0 <= 0)
// if we don't have CLOCK_THREAD_CPUTIME_ID, we have to just use elapsed realtime instead
clockId = CLOCK_REALTIME;
# if (_POSIX_THREAD_CPUTIME-0 == 0)
// detect availablility of CLOCK_THREAD_CPUTIME_ID
static QBasicAtomicInt sUseThreadCpuTime = Q_BASIC_ATOMIC_INITIALIZER(-2);
int useThreadCpuTime = sUseThreadCpuTime.load();
if (useThreadCpuTime == -2) {
// sysconf() will return either -1L or _POSIX_VERSION
// (don't care about sysconf's exact return value)
useThreadCpuTime = sysconf(_SC_THREAD_CPUTIME) == -1L ? -1 : 0 ;
sUseThreadCpuTime.store(useThreadCpuTime); // might happen multiple times, but doesn't matter
}
if (useThreadCpuTime != -1)
clockId = CLOCK_THREAD_CPUTIME_ID;
# endif
#else
clockId = CLOCK_THREAD_CPUTIME_ID;
#endif
struct timespec ts;
if (clock_gettime(clockId, &ts) == -1)
return 0;
return (ts.tv_sec * 1000000000) + ts.tv_nsec;
#else
// no clock_gettime(), fall back to wall time
struct timeval tv;
gettimeofday(&tv, 0);
return (tv.tv_sec * 1000000) + tv.tv_usec;
#endif
}
#elif defined(Q_OS_WIN)
static qint64 getticks()
{
LARGE_INTEGER x;
if (!QueryPerformanceCounter(&x))
return 0;
return x.QuadPart;
}
#endif
static double elapsed(qint64 after, qint64 before)
{
return double(after - before);

View File

@ -1031,7 +1031,8 @@
// critical definitions. (Reported as Intel Issue ID 6000117277)
# define __USE_CONSTEXPR 1
# define __USE_NOEXCEPT 1
# elif defined(Q_CC_MSVC) && (defined(Q_CC_CLANG) || defined(Q_CC_INTEL))
# endif
# if defined(Q_CC_MSVC) && defined(Q_CC_CLANG)
// Clang and the Intel compiler support more C++ features than the Microsoft compiler
// so make sure we don't enable them if the MS headers aren't properly adapted.
# ifndef _HAS_CONSTEXPR
@ -1058,7 +1059,8 @@
# ifndef _HAS_VARIADIC_TEMPLATES
# undef Q_COMPILER_VARIADIC_TEMPLATES
# endif
# elif defined(_LIBCPP_VERSION)
# endif
# if defined(_LIBCPP_VERSION)
// libc++ uses __has_feature(cxx_atomic), so disable the feature if the compiler
// doesn't support it. That's required for the Intel compiler 14.x or earlier on OS X, for example.
# if !__has_feature(cxx_atomic)

View File

@ -1179,6 +1179,12 @@ bool qSharedBuild() Q_DECL_NOTHROW
\value WV_None Operating system other than Windows.
\omitvalue WV_CE
\omitvalue WV_CENET
\omitvalue WV_CE_5
\omitvalue WV_CE_6
\omitvalue WV_CE_based
\sa MacVersion
*/
@ -1255,7 +1261,7 @@ bool qSharedBuild() Q_DECL_NOTHROW
\macro Q_OS_DARWIN
\relates <QtGlobal>
Defined on Darwin-based operating systems such as \macOS, iOS, watchOS, and tvOS.
Defined on Darwin-based operating systems such as \macos, iOS, watchOS, and tvOS.
*/
/*!

View File

@ -78,6 +78,7 @@
1: The feature is available
*/
#define QT_CONFIG(feature) (1/QT_FEATURE_##feature == 1)
#define QT_REQUIRE_CONFIG(feature) Q_STATIC_ASSERT_X(QT_FEATURE_##feature == 1, "Required feature " #feature " for file " __FILE__ " not vailable.")
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
# define QT_NO_UNSHARABLE_CONTAINERS

View File

@ -110,7 +110,13 @@ public:
WV_6_1 = WV_WINDOWS7,
WV_6_2 = WV_WINDOWS8,
WV_6_3 = WV_WINDOWS8_1,
WV_10_0 = WV_WINDOWS10
WV_10_0 = WV_WINDOWS10,
WV_CE = 0x0100,
WV_CENET = 0x0200,
WV_CE_5 = 0x0300,
WV_CE_6 = 0x0400,
WV_CE_based = 0x0f00
};
#if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN)
QT_DEPRECATED_X("Use QOperatingSystemVersion::current()") static const WinVersion WindowsVersion;

View File

@ -38,14 +38,17 @@
****************************************************************************/
#include "qjnihelpers_p.h"
#include "qjni_p.h"
#include "qmutex.h"
#include "qlist.h"
#include "qsemaphore.h"
#include "qsharedpointer.h"
#include "qvector.h"
#include "qthread.h"
#include <QtCore/qrunnable.h>
#include <deque>
#include <memory>
QT_BEGIN_NAMESPACE
@ -60,6 +63,22 @@ static jmethodID g_hideSplashScreenMethodID = Q_NULLPTR;
Q_GLOBAL_STATIC(std::deque<QtAndroidPrivate::Runnable>, g_pendingRunnables);
Q_GLOBAL_STATIC(QMutex, g_pendingRunnablesMutex);
class PermissionsResultClass : public QObject
{
Q_OBJECT
public:
PermissionsResultClass(const QtAndroidPrivate::PermissionsResultFunc &func) : m_func(func) {}
Q_INVOKABLE void sendResult(const QtAndroidPrivate::PermissionsHash &result) { m_func(result); }
private:
QtAndroidPrivate::PermissionsResultFunc m_func;
};
typedef QHash<int, QSharedPointer<PermissionsResultClass>> PendingPermissionRequestsHash;
Q_GLOBAL_STATIC(PendingPermissionRequestsHash, g_pendingPermissionRequests);
Q_GLOBAL_STATIC(QMutex, g_pendingPermissionRequestsMutex);
Q_GLOBAL_STATIC(QAtomicInt, g_requestPermissionsRequestCode);
// function called from Java from Android UI thread
static void runPendingCppRunnables(JNIEnv */*env*/, jobject /*obj*/)
{
@ -81,9 +100,43 @@ namespace {
QMutex mutex;
QVector<QtAndroidPrivate::GenericMotionEventListener *> listeners;
};
enum {
PERMISSION_GRANTED = 0
};
}
Q_GLOBAL_STATIC(GenericMotionEventListeners, g_genericMotionEventListeners)
static void sendRequestPermissionsResult(JNIEnv *env, jobject /*obj*/, jint requestCode,
jobjectArray permissions, jintArray grantResults)
{
g_pendingPermissionRequestsMutex->lock();
auto it = g_pendingPermissionRequests->find(requestCode);
if (it == g_pendingPermissionRequests->end()) {
g_pendingPermissionRequestsMutex->unlock();
// show an error or something ?
return;
}
g_pendingPermissionRequestsMutex->unlock();
Qt::ConnectionType connection = QThread::currentThread() == it.value()->thread() ? Qt::DirectConnection : Qt::BlockingQueuedConnection;
QtAndroidPrivate::PermissionsHash hash;
const int size = env->GetArrayLength(permissions);
std::unique_ptr<jint[]> results(new jint[size]);
env->GetIntArrayRegion(grantResults, 0, size, results.get());
for (int i = 0 ; i < size; ++i) {
const auto &permission = QJNIObjectPrivate(env->GetObjectArrayElement(permissions, i)).toString();
auto value = results[i] == PERMISSION_GRANTED ?
QtAndroidPrivate::PermissionsResult::Granted :
QtAndroidPrivate::PermissionsResult::Denied;
hash[permission] = value;
}
QMetaObject::invokeMethod(it.value().data(), "sendResult", connection, Q_ARG(QtAndroidPrivate::PermissionsHash, hash));
g_pendingPermissionRequestsMutex->lock();
g_pendingPermissionRequests->erase(it);
g_pendingPermissionRequestsMutex->unlock();
}
static jboolean dispatchGenericMotionEvent(JNIEnv *, jclass, jobject event)
{
jboolean ret = JNI_FALSE;
@ -328,7 +381,8 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
{"dispatchGenericMotionEvent", "(Landroid/view/MotionEvent;)Z", reinterpret_cast<void *>(dispatchGenericMotionEvent)},
{"dispatchKeyEvent", "(Landroid/view/KeyEvent;)Z", reinterpret_cast<void *>(dispatchKeyEvent)},
{"setNativeActivity", "(Landroid/app/Activity;)V", reinterpret_cast<void *>(setNativeActivity)},
{"setNativeService", "(Landroid/app/Service;)V", reinterpret_cast<void *>(setNativeService)}
{"setNativeService", "(Landroid/app/Service;)V", reinterpret_cast<void *>(setNativeService)},
{"sendRequestPermissionsResult", "(I[Ljava/lang/String;[I)V", reinterpret_cast<void *>(sendRequestPermissionsResult)},
};
const bool regOk = (env->RegisterNatives(jQtNative, methods, sizeof(methods) / sizeof(methods[0])) == JNI_OK);
@ -411,6 +465,70 @@ void QtAndroidPrivate::runOnAndroidThreadSync(const QtAndroidPrivate::Runnable &
sem->tryAcquire(1, timeoutMs);
}
void QtAndroidPrivate::requestPermissions(JNIEnv *env, const QStringList &permissions, const QtAndroidPrivate::PermissionsResultFunc &callbackFunc, bool directCall)
{
if (androidSdkVersion() < 23 || !activity()) {
QHash<QString, QtAndroidPrivate::PermissionsResult> res;
for (const auto &perm : permissions)
res[perm] = checkPermission(perm);
callbackFunc(res);
return;
}
// Check API 23+ permissions
const int requestCode = (*g_requestPermissionsRequestCode)++;
if (!directCall) {
g_pendingPermissionRequestsMutex->lock();
(*g_pendingPermissionRequests)[requestCode] = QSharedPointer<PermissionsResultClass>::create(callbackFunc);
g_pendingPermissionRequestsMutex->unlock();
}
runOnAndroidThread([permissions, callbackFunc, requestCode, directCall] {
if (directCall) {
g_pendingPermissionRequestsMutex->lock();
(*g_pendingPermissionRequests)[requestCode] = QSharedPointer<PermissionsResultClass>::create(callbackFunc);
g_pendingPermissionRequestsMutex->unlock();
}
QJNIEnvironmentPrivate env;
auto array = env->NewObjectArray(permissions.size(), env->FindClass("java/lang/String"), nullptr);
int index = 0;
for (const auto &perm : permissions)
env->SetObjectArrayElement(array, index++, QJNIObjectPrivate::fromString(perm).object());
QJNIObjectPrivate(activity()).callMethod<void>("requestPermissions", "([Ljava/lang/String;I)V", array, requestCode);
env->DeleteLocalRef(array);
}, env);
}
QHash<QString, QtAndroidPrivate::PermissionsResult> QtAndroidPrivate::requestPermissionsSync(JNIEnv *env, const QStringList &permissions, int timeoutMs)
{
QSharedPointer<QHash<QString, QtAndroidPrivate::PermissionsResult>> res(new QHash<QString, QtAndroidPrivate::PermissionsResult>());
QSharedPointer<QSemaphore> sem(new QSemaphore);
requestPermissions(env, permissions, [sem, res](const QHash<QString, PermissionsResult> &result){
*res = result;
sem->release();
}, true);
sem->tryAcquire(1, timeoutMs);
return *res;
}
QtAndroidPrivate::PermissionsResult QtAndroidPrivate::checkPermission(const QString &permission)
{
const auto res = QJNIObjectPrivate::callStaticMethod<jint>("org/qtproject/qt5/android/QtNative",
"checkSelfPermission",
"(Ljava/lang/String;)I",
QJNIObjectPrivate::fromString(permission).object());
return res == PERMISSION_GRANTED ? PermissionsResult::Granted : PermissionsResult::Denied;
}
bool QtAndroidPrivate::shouldShowRequestPermissionRationale(const QString &permission)
{
if (androidSdkVersion() < 23 || !activity())
return false;
return QJNIObjectPrivate(activity()).callMethod<jboolean>("shouldShowRequestPermissionRationale", "(Ljava/lang/String;)Z",
QJNIObjectPrivate::fromString(permission).object());
}
void QtAndroidPrivate::registerGenericMotionEventListener(QtAndroidPrivate::GenericMotionEventListener *listener)
{
QMutexLocker locker(&g_genericMotionEventListeners()->mutex);
@ -441,3 +559,5 @@ void QtAndroidPrivate::hideSplashScreen(JNIEnv *env)
}
QT_END_NAMESPACE
#include "qjnihelpers.moc"

View File

@ -58,6 +58,7 @@
QT_BEGIN_NAMESPACE
class QRunnable;
class QStringList;
namespace QtAndroidPrivate
{
@ -97,7 +98,13 @@ namespace QtAndroidPrivate
virtual bool handleKeyEvent(jobject event) = 0;
};
enum class PermissionsResult {
Granted,
Denied
};
typedef QHash<QString, QtAndroidPrivate::PermissionsResult> PermissionsHash;
typedef std::function<void()> Runnable;
typedef std::function<void(const PermissionsHash &)> PermissionsResultFunc;
Q_CORE_EXPORT jobject activity();
Q_CORE_EXPORT jobject service();
@ -109,6 +116,10 @@ namespace QtAndroidPrivate
Q_CORE_EXPORT void runOnAndroidThread(const Runnable &runnable, JNIEnv *env);
Q_CORE_EXPORT void runOnAndroidThreadSync(const Runnable &runnable, JNIEnv *env, int timeoutMs = INT_MAX);
Q_CORE_EXPORT void runOnUiThread(QRunnable *runnable, JNIEnv *env);
Q_CORE_EXPORT void requestPermissions(JNIEnv *env, const QStringList &permissions, const PermissionsResultFunc &callbackFunc, bool directCall = false);
Q_CORE_EXPORT QHash<QString, PermissionsResult> requestPermissionsSync(JNIEnv *env, const QStringList &permissions, int timeoutMs = INT_MAX);
Q_CORE_EXPORT PermissionsResult checkPermission(const QString &permission);
Q_CORE_EXPORT bool shouldShowRequestPermissionRationale(const QString &permission);
Q_CORE_EXPORT void handleActivityResult(jint requestCode, jint resultCode, jobject data);
Q_CORE_EXPORT void registerActivityResultListener(ActivityResultListener *listener);

View File

@ -572,10 +572,9 @@ void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
const QString file = data.name + QLatin1String(".xml");
// shared-mime-info since 1.3 lowercases the xml files
QStringList mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QString::fromLatin1("mime/") + file.toLower());
if (mimeFiles.isEmpty()) {
mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QString::fromLatin1("mime/") + file); // pre-1.3
}
QStringList mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/") + file.toLower());
if (mimeFiles.isEmpty())
mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/") + file); // pre-1.3
if (mimeFiles.isEmpty()) {
qWarning() << "No file found for" << file << ", even though update-mime-info said it would exist.\n"
"Either it was just removed, or the directory doesn't have executable permission..."
@ -807,7 +806,7 @@ bool QMimeXMLProvider::load(const QString &fileName, QString *errorMessage)
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (errorMessage)
*errorMessage = QString::fromLatin1("Cannot open %1: %2").arg(fileName, file.errorString());
*errorMessage = QLatin1String("Cannot open ") + fileName + QLatin1String(": ") + file.errorString();
return false;
}

View File

@ -135,8 +135,8 @@ public:
template <class Rep, class Period>
bool try_lock_for(std::chrono::duration<Rep, Period> duration)
{
// § 30.4.1.3.5 [thread.timedmutex.requirements] specifies that a
// duration less than or equal to duration.zero() shall result in a
// N4606 § 30.4.1.3 [thread.timedmutex.requirements]/5 specifies that
// a duration less than or equal to duration.zero() shall result in a
// try_lock, unlike QMutex's tryLock with a negative duration which
// results in a lock.
@ -150,7 +150,7 @@ public:
bool try_lock_until(std::chrono::time_point<Clock, Duration> timePoint)
{
// Implemented in terms of try_lock_for to honor the similar
// requirement in § 30.4.1.3.12 [thread.timedmutex.requirements]
// requirement in N4606 § 30.4.1.3 [thread.timedmutex.requirements]/12.
return try_lock_for(timePoint - Clock::now());
}

View File

@ -468,6 +468,9 @@ static inline quint64 qCpuFeatures()
#define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length) \
for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((4 - ((reinterpret_cast<quintptr>(ptr) >> 2) & 0x3)) & 0x3))); ++i)
#define ALIGNMENT_PROLOGUE_32BYTES(ptr, i, length) \
for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((8 - ((reinterpret_cast<quintptr>(ptr) >> 2) & 0x7)) & 0x7))); ++i)
QT_END_NAMESPACE
#endif // QSIMD_P_H

View File

@ -1440,7 +1440,8 @@ public:
QStringRef mid(int pos, int n = -1) const Q_REQUIRED_RESULT;
void truncate(int pos) Q_DECL_NOTHROW { m_size = qBound(0, pos, m_size); }
void chop(int n) Q_DECL_NOTHROW {
void chop(int n) Q_DECL_NOTHROW
{
if (n >= m_size)
m_size = 0;
else if (n > 0)

View File

@ -447,6 +447,17 @@ void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegularEx
#endif // QT_NO_REGULAREXPRESSION
#endif // QT_BOOTSTRAPPED
static int accumulatedSize(const QStringList &list, int seplen)
{
int result = 0;
if (!list.isEmpty()) {
for (const auto &e : list)
result += e.size() + seplen;
result -= seplen;
}
return result;
}
/*!
\fn QString QStringList::join(const QString &separator) const
@ -464,15 +475,9 @@ void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegularEx
*/
QString QtPrivate::QStringList_join(const QStringList *that, const QChar *sep, int seplen)
{
int totalLength = 0;
const int totalLength = accumulatedSize(*that, seplen);
const int size = that->size();
for (int i = 0; i < size; ++i)
totalLength += that->at(i).size();
if(size > 0)
totalLength += seplen * (size - 1);
QString res;
if (totalLength == 0)
return res;
@ -485,6 +490,27 @@ QString QtPrivate::QStringList_join(const QStringList *that, const QChar *sep, i
return res;
}
/*!
\fn QString QStringList::join(QLatin1String separator) const
\since 5.8
\overload join()
*/
QString QtPrivate::QStringList_join(const QStringList &list, QLatin1String sep)
{
QString result;
if (!list.isEmpty()) {
result.reserve(accumulatedSize(list, sep.size()));
const auto end = list.end();
auto it = list.begin();
result += *it;
while (++it != end) {
result += sep;
result += *it;
}
}
return result;
}
/*!
\fn QStringList QStringList::operator+(const QStringList &other) const

View File

@ -73,6 +73,7 @@ public:
inline int removeDuplicates();
inline QString join(const QString &sep) const;
inline QString join(QLatin1String sep) const;
inline QString join(QChar sep) const;
inline QStringList filter(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
@ -159,6 +160,7 @@ namespace QtPrivate {
void Q_CORE_EXPORT QStringList_sort(QStringList *that, Qt::CaseSensitivity cs);
int Q_CORE_EXPORT QStringList_removeDuplicates(QStringList *that);
QString Q_CORE_EXPORT QStringList_join(const QStringList *that, const QChar *sep, int seplen);
Q_CORE_EXPORT QString QStringList_join(const QStringList &list, QLatin1String sep);
QStringList Q_CORE_EXPORT QStringList_filter(const QStringList *that, const QString &str,
Qt::CaseSensitivity cs);
@ -200,6 +202,11 @@ inline QString QListSpecialMethods<QString>::join(const QString &sep) const
return QtPrivate::QStringList_join(self(), sep.constData(), sep.length());
}
QString QListSpecialMethods<QString>::join(QLatin1String sep) const
{
return QtPrivate::QStringList_join(*self(), sep);
}
inline QString QListSpecialMethods<QString>::join(QChar sep) const
{
return QtPrivate::QStringList_join(self(), &sep, 1);

View File

@ -116,8 +116,7 @@ static QString generateSubObjectXml(QObject *object)
for ( ; it != end; ++it) {
QString name = (*it)->objectName();
if (!name.isEmpty() && QDBusUtil::isValidPartOfObjectPath(name))
retval += QString::fromLatin1(" <node name=\"%1\"/>\n")
.arg(name);
retval += QLatin1String(" <node name=\"") + name + QLatin1String("\"/>\n");
}
return retval;
}
@ -192,8 +191,7 @@ QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node
node.children.constEnd();
for ( ; it != end; ++it)
if (it->obj || !it->children.isEmpty())
xml_data += QString::fromLatin1(" <node name=\"%1\"/>\n")
.arg(it->name);
xml_data += QLatin1String(" <node name=\"") + it->name + QLatin1String("\"/>\n");
}
xml_data += QLatin1String("</node>\n");

View File

@ -134,7 +134,8 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
Q_ASSERT(dest->format > QImage::Format_Indexed8);
Q_ASSERT(src->format > QImage::Format_Indexed8);
const int buffer_size = 2048;
uint buffer[buffer_size];
uint buf[buffer_size];
uint *buffer = buf;
const QPixelLayout *srcLayout = &qPixelLayouts[src->format];
const QPixelLayout *destLayout = &qPixelLayouts[dest->format];
const uchar *srcData = src->data;
@ -169,11 +170,16 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
int x = 0;
while (x < src->width) {
dither.x = x;
int l = qMin(src->width - x, buffer_size);
int l = src->width - x;
if (destLayout->bpp == QPixelLayout::BPP32)
buffer = reinterpret_cast<uint *>(destData) + x;
else
l = qMin(l, buffer_size);
const uint *ptr = fetch(buffer, srcData, x, l);
ptr = convertToARGB32PM(buffer, ptr, l, 0, ditherPtr);
ptr = convertFromARGB32PM(buffer, ptr, l, 0, ditherPtr);
store(destData, ptr, x, l);
if (ptr != reinterpret_cast<uint *>(destData))
store(destData, ptr, x, l);
x += l;
}
srcData += src->bytes_per_line;

View File

@ -569,7 +569,7 @@ bool QImageReaderPrivate::initHandler()
do {
file->setFileName(fileName + QLatin1Char('.')
+ QString::fromLatin1(extensions.at(currentExtension++).constData()));
+ QLatin1String(extensions.at(currentExtension++).constData()));
file->open(QIODevice::ReadOnly);
} while (!file->isOpen() && currentExtension < extensions.size());

View File

@ -52,7 +52,7 @@
#include <QtCore/qvector.h>
#include <QtCore/qset.h> // ### Qt 6: Remove
#include <QtCore/qurl.h>
#include <QtCore/qfile.h> // ### Qt 6: Replace by <qiodevice.h> and forward declare QFile
#include <QtCore/qfile.h> // ### Qt 6: Replace by <QtCore/qiodevice.h> and forward declare QFile
#include <QtGui/qvector2d.h>
#include <QtGui/qtouchdevice.h> // ### Qt 6: Replace by forward declaration

View File

@ -1211,9 +1211,13 @@ QString QKeySequence::encodeString(int key)
static inline void addKey(QString &str, const QString &theKey, QKeySequence::SequenceFormat format)
{
if (!str.isEmpty())
str += (format == QKeySequence::NativeText) ? QCoreApplication::translate("QShortcut", "+")
: QString::fromLatin1("+");
if (!str.isEmpty()) {
if (format == QKeySequence::NativeText)
str += QCoreApplication::translate("QShortcut", "+");
else
str += QLatin1Char('+');
}
str += theKey;
}

View File

@ -667,6 +667,10 @@ void QScreenPrivate::updatePrimaryOrientation()
that are not part of the application, window system frames, and so
on.
\warning Grabbing windows that are not part of the application is
not supported on systems such as iOS, where sandboxing/security
prevents reading pixels of windows not owned by the application.
The grabWindow() function grabs pixels from the screen, not from
the window, i.e. if there is another window partially or entirely
over the one you grab, you get pixels from the overlying window,

View File

@ -99,6 +99,11 @@ SOURCES += \
painting/qplatformbackingstore.cpp \
painting/qpathsimplifier.cpp
darwin {
HEADERS += painting/qcoregraphics_p.h
SOURCES += painting/qcoregraphics.mm
}
SSE2_SOURCES += painting/qdrawhelper_sse2.cpp
SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \

View File

@ -0,0 +1,566 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qcoregraphics_p.h"
#include <private/qcore_mac_p.h>
#include <qpa/qplatformpixmap.h>
#include <QtGui/qicon.h>
#include <QtGui/private/qpaintengine_p.h>
#include <QtCore/qdebug.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qoperatingsystemversion.h>
QT_BEGIN_NAMESPACE
// ---------------------- Images ----------------------
CGImageRef qt_mac_toCGImage(const QImage &inImage)
{
CGImageRef cgImage = inImage.toCGImage();
if (cgImage)
return cgImage;
// Convert image data to a known-good format if the fast conversion fails.
return inImage.convertToFormat(QImage::Format_ARGB32_Premultiplied).toCGImage();
}
CGImageRef qt_mac_toCGImageMask(const QImage &image)
{
static const auto deleter = [](void *image, const void *, size_t) { delete static_cast<QImage *>(image); };
QCFType<CGDataProviderRef> dataProvider =
CGDataProviderCreateWithData(new QImage(image), image.bits(),
image.byteCount(), deleter);
return CGImageMaskCreate(image.width(), image.height(), 8, image.depth(),
image.bytesPerLine(), dataProvider, NULL, false);
}
OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage)
{
// Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev)
OSStatus err = noErr;
#ifdef Q_OS_MACOS
require_action(inContext != NULL, InvalidContext, err = paramErr);
require_action(inBounds != NULL, InvalidBounds, err = paramErr);
require_action(inImage != NULL, InvalidImage, err = paramErr);
#endif
CGContextSaveGState( inContext );
CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds));
CGContextScaleCTM(inContext, 1, -1);
CGContextDrawImage(inContext, *inBounds, inImage);
CGContextRestoreGState(inContext);
#ifdef Q_OS_MACOS
InvalidImage:
InvalidBounds:
InvalidContext:
#endif
return err;
}
QImage qt_mac_toQImage(CGImageRef image)
{
const size_t w = CGImageGetWidth(image),
h = CGImageGetHeight(image);
QImage ret(w, h, QImage::Format_ARGB32_Premultiplied);
ret.fill(Qt::transparent);
CGRect rect = CGRectMake(0, 0, w, h);
QMacCGContext ctx(&ret);
qt_mac_drawCGImage(ctx, &rect, image);
return ret;
}
#ifdef Q_OS_MACOS
QT_END_NAMESPACE
@interface NSGraphicsContext (QtAdditions)
+ (NSGraphicsContext *)qt_graphicsContextWithCGContext:(CGContextRef)graphicsPort flipped:(BOOL)initialFlippedState;
@end
@implementation NSGraphicsContext (QtAdditions)
+ (NSGraphicsContext *)qt_graphicsContextWithCGContext:(CGContextRef)graphicsPort flipped:(BOOL)initialFlippedState
{
#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_10, __IPHONE_NA)
if (QT_PREPEND_NAMESPACE(QOperatingSystemVersion::current()) >= QT_PREPEND_NAMESPACE(QOperatingSystemVersion::OSXYosemite))
return [self graphicsContextWithCGContext:graphicsPort flipped:initialFlippedState];
#endif
return [self graphicsContextWithGraphicsPort:graphicsPort flipped:initialFlippedState];
}
@end
QT_BEGIN_NAMESPACE
static NSImage *qt_mac_cgimage_to_nsimage(CGImageRef image)
{
NSImage *newImage = [[NSImage alloc] initWithCGImage:image size:NSZeroSize];
return newImage;
}
NSImage *qt_mac_create_nsimage(const QPixmap &pm)
{
if (pm.isNull())
return 0;
QImage image = pm.toImage();
CGImageRef cgImage = qt_mac_toCGImage(image);
NSImage *nsImage = qt_mac_cgimage_to_nsimage(cgImage);
CGImageRelease(cgImage);
return nsImage;
}
NSImage *qt_mac_create_nsimage(const QIcon &icon)
{
if (icon.isNull())
return nil;
NSImage *nsImage = [[NSImage alloc] init];
foreach (QSize size, icon.availableSizes()) {
QPixmap pm = icon.pixmap(size);
QImage image = pm.toImage();
CGImageRef cgImage = qt_mac_toCGImage(image);
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
[nsImage addRepresentation:imageRep];
[imageRep release];
CGImageRelease(cgImage);
}
return nsImage;
}
QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size)
{
const NSSize pixmapSize = NSMakeSize(size.width(), size.height());
QPixmap pixmap(pixmapSize.width, pixmapSize.height);
pixmap.fill(Qt::transparent);
[image setSize:pixmapSize];
const NSRect iconRect = NSMakeRect(0, 0, pixmapSize.width, pixmapSize.height);
QMacCGContext ctx(&pixmap);
if (!ctx)
return QPixmap();
NSGraphicsContext *gc = [NSGraphicsContext qt_graphicsContextWithCGContext:ctx flipped:YES];
if (!gc)
return QPixmap();
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:gc];
[image drawInRect:iconRect fromRect:iconRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil];
[NSGraphicsContext restoreGraphicsState];
return pixmap;
}
#endif // Q_OS_MACOS
// ---------------------- Colors and Brushes ----------------------
QColor qt_mac_toQColor(CGColorRef color)
{
QColor qtColor;
CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(color));
const CGFloat *components = CGColorGetComponents(color);
if (model == kCGColorSpaceModelRGB) {
qtColor.setRgbF(components[0], components[1], components[2], components[3]);
} else if (model == kCGColorSpaceModelCMYK) {
qtColor.setCmykF(components[0], components[1], components[2], components[3]);
} else if (model == kCGColorSpaceModelMonochrome) {
qtColor.setRgbF(components[0], components[0], components[0], components[1]);
} else {
// Colorspace we can't deal with.
qWarning("Qt: qt_mac_toQColor: cannot convert from colorspace model: %d", model);
Q_ASSERT(false);
}
return qtColor;
}
#ifdef Q_OS_MACOS
QColor qt_mac_toQColor(const NSColor *color)
{
QColor qtColor;
NSString *colorSpace = [color colorSpaceName];
if (colorSpace == NSDeviceCMYKColorSpace) {
CGFloat cyan, magenta, yellow, black, alpha;
[color getCyan:&cyan magenta:&magenta yellow:&yellow black:&black alpha:&alpha];
qtColor.setCmykF(cyan, magenta, yellow, black, alpha);
} else {
NSColor *tmpColor;
tmpColor = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace];
CGFloat red, green, blue, alpha;
[tmpColor getRed:&red green:&green blue:&blue alpha:&alpha];
qtColor.setRgbF(red, green, blue, alpha);
}
return qtColor;
}
#endif
QBrush qt_mac_toQBrush(CGColorRef color)
{
QBrush qtBrush;
CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(color));
if (model == kCGColorSpaceModelPattern) {
// Colorspace we can't deal with; the color is drawn directly using a callback.
qWarning("Qt: qt_mac_toQBrush: cannot convert from colorspace model: %d", model);
Q_ASSERT(false);
} else {
qtBrush.setStyle(Qt::SolidPattern);
qtBrush.setColor(qt_mac_toQColor(color));
}
return qtBrush;
}
#ifdef Q_OS_MACOS
static bool qt_mac_isSystemColorOrInstance(const NSColor *color, NSString *colorNameComponent, NSString *className)
{
// We specifically do not want isKindOfClass: here
if ([color.className isEqualToString:className]) // NSPatternColorSpace
return true;
if ([color.catalogNameComponent isEqualToString:@"System"] &&
[color.colorNameComponent isEqualToString:colorNameComponent] &&
[color.colorSpaceName isEqualToString:NSNamedColorSpace])
return true;
return false;
}
QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup)
{
QBrush qtBrush;
// QTBUG-49773: This calls NSDrawMenuItemBackground to render a 1 by n gradient; could use HITheme
if ([color.className isEqualToString:@"NSMenuItemHighlightColor"]) {
qWarning("Qt: qt_mac_toQBrush: cannot convert from NSMenuItemHighlightColor");
return qtBrush;
}
// Not a catalog color or a manifestation of System.windowBackgroundColor;
// only retrieved from NSWindow.backgroundColor directly
if ([color.className isEqualToString:@"NSMetalPatternColor"]) {
// NSTexturedBackgroundWindowMask, could theoretically handle this without private API by
// creating a window with the appropriate properties and then calling NSWindow.backgroundColor.patternImage,
// which returns a texture sized 1 by (window height, including frame), backed by a CGPattern
// which follows the window key state... probably need to allow QBrush to store a function pointer
// like CGPattern does
qWarning("Qt: qt_mac_toQBrush: cannot convert from NSMetalPatternColor");
return qtBrush;
}
// No public API to get these colors/stops;
// both accurately obtained through runtime object inspection on OS X 10.11
// (the NSColor object has NSGradient i-vars for both color groups)
if (qt_mac_isSystemColorOrInstance(color, @"_sourceListBackgroundColor", @"NSSourceListBackgroundColor")) {
QLinearGradient gradient;
if (colorGroup == QPalette::Active) {
gradient.setColorAt(0, QColor(233, 237, 242));
gradient.setColorAt(0.5, QColor(225, 229, 235));
gradient.setColorAt(1, QColor(209, 216, 224));
} else {
gradient.setColorAt(0, QColor(248, 248, 248));
gradient.setColorAt(0.5, QColor(240, 240, 240));
gradient.setColorAt(1, QColor(235, 235, 235));
}
return QBrush(gradient);
}
// A couple colors are special... they are actually instances of NSGradientPatternColor, which
// override set/setFill/setStroke to instead initialize an internal color
// ([NSColor colorWithCalibratedWhite:0.909804 alpha:1.000000]) while still returning the
// ruled lines pattern image (from OS X 10.4) to the user from -[NSColor patternImage]
// (and providing no public API to get the underlying color without this insanity)
if (qt_mac_isSystemColorOrInstance(color, @"controlColor", @"NSGradientPatternColor") ||
qt_mac_isSystemColorOrInstance(color, @"windowBackgroundColor", @"NSGradientPatternColor")) {
qtBrush.setStyle(Qt::SolidPattern);
qtBrush.setColor(qt_mac_toQColor(color.CGColor));
return qtBrush;
}
if (NSColor *patternColor = [color colorUsingColorSpaceName:NSPatternColorSpace]) {
NSImage *patternImage = patternColor.patternImage;
const QSizeF sz(patternImage.size.width, patternImage.size.height);
// FIXME: QBrush is not resolution independent (QTBUG-49774)
qtBrush.setTexture(qt_mac_toQPixmap(patternImage, sz));
} else {
qtBrush.setStyle(Qt::SolidPattern);
qtBrush.setColor(qt_mac_toQColor(color));
}
return qtBrush;
}
#endif
// ---------------------- Color Management ----------------------
static CGColorSpaceRef m_genericColorSpace = 0;
static QHash<uint32_t, CGColorSpaceRef> m_displayColorSpaceHash;
static bool m_postRoutineRegistered = false;
static void qt_mac_cleanUpMacColorSpaces()
{
if (m_genericColorSpace) {
CFRelease(m_genericColorSpace);
m_genericColorSpace = 0;
}
QHash<uint32_t, CGColorSpaceRef>::const_iterator it = m_displayColorSpaceHash.constBegin();
while (it != m_displayColorSpaceHash.constEnd()) {
if (it.value())
CFRelease(it.value());
++it;
}
m_displayColorSpaceHash.clear();
}
static CGColorSpaceRef qt_mac_displayColorSpace(const QWindow *window)
{
CGColorSpaceRef colorSpace = 0;
uint32_t displayID = 0;
#ifdef Q_OS_MACOS
if (window == 0) {
displayID = CGMainDisplayID();
} else {
displayID = CGMainDisplayID();
/*
### get correct display
const QRect &qrect = window->geometry();
CGRect rect = CGRectMake(qrect.x(), qrect.y(), qrect.width(), qrect.height());
CGDisplayCount throwAway;
CGDisplayErr dErr = CGGetDisplaysWithRect(rect, 1, &displayID, &throwAway);
if (dErr != kCGErrorSuccess)
return macDisplayColorSpace(0); // fall back on main display
*/
}
if ((colorSpace = m_displayColorSpaceHash.value(displayID)))
return colorSpace;
colorSpace = CGDisplayCopyColorSpace(displayID);
#else
Q_UNUSED(window);
#endif
if (colorSpace == 0)
colorSpace = CGColorSpaceCreateDeviceRGB();
m_displayColorSpaceHash.insert(displayID, colorSpace);
if (!m_postRoutineRegistered) {
m_postRoutineRegistered = true;
qAddPostRoutine(qt_mac_cleanUpMacColorSpaces);
}
return colorSpace;
}
CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice)
{
Q_UNUSED(paintDevice);
// FIXME: Move logic into each paint device once Qt has support for color spaces
return qt_mac_displayColorSpace(0);
// The following code seems to take care of QWidget, but in reality doesn't, as
// qt_mac_displayColorSpace ignores the argument and always uses the main display.
#if 0
bool isWidget = (paintDevice->devType() == QInternal::Widget);
return qt_mac_displayColorSpace(isWidget ? static_cast<const QWidget *>(paintDevice)->window() : 0);
#endif
}
CGColorSpaceRef qt_mac_genericColorSpace()
{
#if 0
if (!m_genericColorSpace) {
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
} else
{
m_genericColorSpace = CGColorSpaceCreateDeviceRGB();
}
if (!m_postRoutineRegistered) {
m_postRoutineRegistered = true;
qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces);
}
}
return m_genericColorSpace;
#else
// Just return the main display colorspace for the moment.
return qt_mac_displayColorSpace(0);
#endif
}
// ---------------------- Geometry Helpers ----------------------
void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform)
{
CGAffineTransform old_xform = CGAffineTransformIdentity;
if (orig_xform) { //setup xforms
old_xform = CGContextGetCTM(hd);
CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform));
CGContextConcatCTM(hd, *orig_xform);
}
//do the clipping
CGContextBeginPath(hd);
if (rgn.isEmpty()) {
CGContextAddRect(hd, CGRectMake(0, 0, 0, 0));
} else {
for (const QRect &r : rgn) {
CGRect mac_r = CGRectMake(r.x(), r.y(), r.width(), r.height());
CGContextAddRect(hd, mac_r);
}
}
CGContextClip(hd);
if (orig_xform) {//reset xforms
CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd)));
CGContextConcatCTM(hd, old_xform);
}
}
// move to QRegion?
void qt_mac_scale_region(QRegion *region, qreal scaleFactor)
{
if (!region || !region->rectCount())
return;
QVector<QRect> scaledRects;
scaledRects.reserve(region->rectCount());
for (const QRect &rect : *region)
scaledRects.append(QRect(rect.topLeft() * scaleFactor, rect.size() * scaleFactor));
region->setRects(&scaledRects[0], scaledRects.count());
}
// ---------------------- QMacCGContext ----------------------
QMacCGContext::QMacCGContext(QPaintDevice *paintDevice) : context(0)
{
// In Qt 5, QWidget and QPixmap (and QImage) paint devices are all QImages under the hood.
QImage *image = 0;
if (paintDevice->devType() == QInternal::Image) {
image = static_cast<QImage *>(paintDevice);
} else if (paintDevice->devType() == QInternal::Pixmap) {
const QPixmap *pm = static_cast<const QPixmap*>(paintDevice);
QPlatformPixmap *data = const_cast<QPixmap *>(pm)->data_ptr().data();
if (data && data->classId() == QPlatformPixmap::RasterClass) {
image = data->buffer();
} else {
qDebug("QMacCGContext: Unsupported pixmap class");
}
} else if (paintDevice->devType() == QInternal::Widget) {
// TODO test: image = static_cast<QImage *>(static_cast<const QWidget *>(paintDevice)->backingStore()->paintDevice());
qDebug("QMacCGContext: not implemented: Widget class");
}
if (!image)
return; // Context type not supported.
CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(paintDevice);
uint flags = kCGImageAlphaPremultipliedFirst;
flags |= kCGBitmapByteOrder32Host;
context = CGBitmapContextCreate(image->bits(), image->width(), image->height(),
8, image->bytesPerLine(), colorspace, flags);
CGContextTranslateCTM(context, 0, image->height());
CGContextScaleCTM(context, 1, -1);
}
QMacCGContext::QMacCGContext(QPainter *painter) : context(0)
{
QPaintEngine *paintEngine = painter->paintEngine();
// Handle the case of QMacPrintEngine, which has an internal QCoreGraphicsPaintEngine
while (QPaintEngine *aggregateEngine = QPaintEnginePrivate::get(paintEngine)->aggregateEngine())
paintEngine = aggregateEngine;
paintEngine->syncState();
if (Qt::HANDLE handle = QPaintEnginePrivate::get(paintEngine)->nativeHandle()) {
context = static_cast<CGContextRef>(handle);
return;
}
int devType = painter->device()->devType();
if (paintEngine->type() == QPaintEngine::Raster
&& (devType == QInternal::Widget ||
devType == QInternal::Pixmap ||
devType == QInternal::Image)) {
CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(paintEngine->paintDevice());
uint flags = kCGImageAlphaPremultipliedFirst;
#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
flags |= kCGBitmapByteOrder32Host;
#endif
const QImage *image = static_cast<const QImage *>(paintEngine->paintDevice());
context = CGBitmapContextCreate((void *)image->bits(), image->width(), image->height(),
8, image->bytesPerLine(), colorspace, flags);
// Invert y axis
CGContextTranslateCTM(context, 0, image->height());
CGContextScaleCTM(context, 1, -1);
const qreal devicePixelRatio = image->devicePixelRatio();
if (devType == QInternal::Widget) {
// Set the clip rect which is an intersection of the system clip
// and the painter clip. To make matters more interesting these
// are in device pixels and device-independent pixels, respectively.
QRegion clip = painter->paintEngine()->systemClip(); // get system clip in device pixels
QTransform native = painter->deviceTransform(); // get device transform. dx/dy is in device pixels
if (painter->hasClipping()) {
QRegion r = painter->clipRegion(); // get painter clip, which is in device-independent pixels
qt_mac_scale_region(&r, devicePixelRatio); // scale painter clip to device pixels
r.translate(native.dx(), native.dy());
if (clip.isEmpty())
clip = r;
else
clip &= r;
}
qt_mac_clip_cg(context, clip, 0); // clip in device pixels
// Scale the context so that painting happens in device-independent pixels
CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
CGContextTranslateCTM(context, native.dx() / devicePixelRatio, native.dy() / devicePixelRatio);
} else {
// Scale to paint in device-independent pixels
CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
}
} else {
qDebug() << "QMacCGContext:: Unsupported painter devtype type" << devType;
}
}
QT_END_NAMESPACE

View File

@ -0,0 +1,121 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QCOREGRAPHICS_P_H
#define QCOREGRAPHICS_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtGui/private/qtguiglobal_p.h>
#include <QtGui/qregion.h>
#include <QtGui/qpalette.h>
#include <CoreGraphics/CoreGraphics.h>
#ifdef Q_OS_MACOS
#include <AppKit/AppKit.h>
#endif
QT_BEGIN_NAMESPACE
#ifdef Q_OS_MACOS
Q_GUI_EXPORT NSImage *qt_mac_create_nsimage(const QPixmap &pm);
Q_GUI_EXPORT NSImage *qt_mac_create_nsimage(const QIcon &icon);
Q_GUI_EXPORT QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size);
#endif
Q_GUI_EXPORT CGImageRef qt_mac_toCGImage(const QImage &qImage);
Q_GUI_EXPORT CGImageRef qt_mac_toCGImageMask(const QImage &qImage);
Q_GUI_EXPORT QImage qt_mac_toQImage(CGImageRef image);
Q_GUI_EXPORT OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage);
Q_GUI_EXPORT CGColorSpaceRef qt_mac_genericColorSpace();
Q_GUI_EXPORT CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice);
Q_GUI_EXPORT void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform);
#ifdef Q_OS_MACOS
Q_GUI_EXPORT QColor qt_mac_toQColor(const NSColor *color);
Q_GUI_EXPORT QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup = QPalette::Normal);
#endif
Q_GUI_EXPORT QColor qt_mac_toQColor(CGColorRef color);
Q_GUI_EXPORT QBrush qt_mac_toQBrush(CGColorRef color);
class Q_GUI_EXPORT QMacCGContext
{
public:
inline QMacCGContext() { context = 0; }
QMacCGContext(QPaintDevice *pdev);
QMacCGContext(QPainter *p);
inline QMacCGContext(CGContextRef cg, bool takeOwnership = false) {
context = cg;
if (!takeOwnership)
CGContextRetain(context);
}
inline QMacCGContext(const QMacCGContext &copy) : context(0) { *this = copy; }
inline ~QMacCGContext() {
if (context)
CGContextRelease(context);
}
inline bool isNull() const { return context; }
inline operator CGContextRef() { return context; }
inline QMacCGContext &operator=(const QMacCGContext &copy) {
if (context)
CGContextRelease(context);
context = copy.context;
CGContextRetain(context);
return *this;
}
inline QMacCGContext &operator=(CGContextRef cg) {
if (context)
CGContextRelease(context);
context = cg;
CGContextRetain(context); //we do not take ownership
return *this;
}
private:
CGContextRef context;
};
QT_END_NAMESPACE
#endif // QCOREGRAPHICS_P_H

View File

@ -3263,342 +3263,72 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
return buffer;
}
static SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
// Untransformed
{
0, // Invalid
fetchUntransformed, // Mono
fetchUntransformed, // MonoLsb
fetchUntransformed, // Indexed8
fetchUntransformedARGB32PM, // RGB32
fetchUntransformed, // ARGB32
fetchUntransformedARGB32PM, // ARGB32_Premultiplied
fetchUntransformedRGB16, // RGB16
fetchUntransformed, // ARGB8565_Premultiplied
fetchUntransformed, // RGB666
fetchUntransformed, // ARGB6666_Premultiplied
fetchUntransformed, // RGB555
fetchUntransformed, // ARGB8555_Premultiplied
fetchUntransformed, // RGB888
fetchUntransformed, // RGB444
fetchUntransformed, // ARGB4444_Premultiplied
fetchUntransformed, // RGBX8888
fetchUntransformed, // RGBA8888
fetchUntransformed, // RGBA8888_Premultiplied
fetchUntransformed, // Format_BGR30
fetchUntransformed, // Format_A2BGR30_Premultiplied
fetchUntransformed, // Format_RGB30
fetchUntransformed, // Format_A2RGB30_Premultiplied
fetchUntransformed, // Alpha8
fetchUntransformed, // Grayscale8
},
// Tiled
{
0, // Invalid
fetchUntransformed, // Mono
fetchUntransformed, // MonoLsb
fetchUntransformed, // Indexed8
fetchUntransformedARGB32PM, // RGB32
fetchUntransformed, // ARGB32
fetchUntransformedARGB32PM, // ARGB32_Premultiplied
fetchUntransformedRGB16, // RGB16
fetchUntransformed, // ARGB8565_Premultiplied
fetchUntransformed, // RGB666
fetchUntransformed, // ARGB6666_Premultiplied
fetchUntransformed, // RGB555
fetchUntransformed, // ARGB8555_Premultiplied
fetchUntransformed, // RGB888
fetchUntransformed, // RGB444
fetchUntransformed, // ARGB4444_Premultiplied
fetchUntransformed, // RGBX8888
fetchUntransformed, // RGBA8888
fetchUntransformed, // RGBA8888_Premultiplied
fetchUntransformed, // BGR30
fetchUntransformed, // A2BGR30_Premultiplied
fetchUntransformed, // RGB30
fetchUntransformed, // A2RGB30_Premultiplied
fetchUntransformed, // Alpha8
fetchUntransformed, // Grayscale8
},
// Transformed
{
0, // Invalid
fetchTransformed<BlendTransformed>, // Mono
fetchTransformed<BlendTransformed>, // MonoLsb
fetchTransformed<BlendTransformed>, // Indexed8
fetchTransformedARGB32PM<BlendTransformed>, // RGB32
fetchTransformed<BlendTransformed>, // ARGB32
fetchTransformedARGB32PM<BlendTransformed>, // ARGB32_Premultiplied
fetchTransformed<BlendTransformed>, // RGB16
fetchTransformed<BlendTransformed>, // ARGB8565_Premultiplied
fetchTransformed<BlendTransformed>, // RGB666
fetchTransformed<BlendTransformed>, // ARGB6666_Premultiplied
fetchTransformed<BlendTransformed>, // RGB555
fetchTransformed<BlendTransformed>, // ARGB8555_Premultiplied
fetchTransformed<BlendTransformed>, // RGB888
fetchTransformed<BlendTransformed>, // RGB444
fetchTransformed<BlendTransformed>, // ARGB4444_Premultiplied
fetchTransformed<BlendTransformed>, // RGBX8888
fetchTransformed<BlendTransformed>, // RGBA8888
fetchTransformed<BlendTransformed>, // RGBA8888_Premultiplied
fetchTransformed<BlendTransformed>, // BGR30
fetchTransformed<BlendTransformed>, // A2BGR30_Premultiplied
fetchTransformed<BlendTransformed>, // RGB30
fetchTransformed<BlendTransformed>, // A2RGB30_Premultiplied
fetchTransformed<BlendTransformed>, // Alpah8
fetchTransformed<BlendTransformed>, // Grayscale8
},
{
0, // TransformedTiled
fetchTransformed<BlendTransformedTiled>, // Mono
fetchTransformed<BlendTransformedTiled>, // MonoLsb
fetchTransformed<BlendTransformedTiled>, // Indexed8
fetchTransformedARGB32PM<BlendTransformedTiled>, // RGB32
fetchTransformed<BlendTransformedTiled>, // ARGB32
fetchTransformedARGB32PM<BlendTransformedTiled>, // ARGB32_Premultiplied
fetchTransformed<BlendTransformedTiled>, // RGB16
fetchTransformed<BlendTransformedTiled>, // ARGB8565_Premultiplied
fetchTransformed<BlendTransformedTiled>, // RGB666
fetchTransformed<BlendTransformedTiled>, // ARGB6666_Premultiplied
fetchTransformed<BlendTransformedTiled>, // RGB555
fetchTransformed<BlendTransformedTiled>, // ARGB8555_Premultiplied
fetchTransformed<BlendTransformedTiled>, // RGB888
fetchTransformed<BlendTransformedTiled>, // RGB444
fetchTransformed<BlendTransformedTiled>, // ARGB4444_Premultiplied
fetchTransformed<BlendTransformedTiled>, // RGBX8888
fetchTransformed<BlendTransformedTiled>, // RGBA8888
fetchTransformed<BlendTransformedTiled>, // RGBA8888_Premultiplied
fetchTransformed<BlendTransformedTiled>, // BGR30
fetchTransformed<BlendTransformedTiled>, // A2BGR30_Premultiplied
fetchTransformed<BlendTransformedTiled>, // RGB30
fetchTransformed<BlendTransformedTiled>, // A2RGB30_Premultiplied
fetchTransformed<BlendTransformedTiled>, // Alpha8
fetchTransformed<BlendTransformedTiled>, // Grayscale8
},
{
0, // Bilinear
fetchTransformedBilinear<BlendTransformedBilinear>, // Mono
fetchTransformedBilinear<BlendTransformedBilinear>, // MonoLsb
fetchTransformedBilinear<BlendTransformedBilinear>, // Indexed8
fetchTransformedBilinearARGB32PM<BlendTransformedBilinear>, // RGB32
fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB32
fetchTransformedBilinearARGB32PM<BlendTransformedBilinear>, // ARGB32_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinear>, // RGB16
fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB8565_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinear>, // RGB666
fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB6666_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinear>, // RGB555
fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB8555_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinear>, // RGB888
fetchTransformedBilinear<BlendTransformedBilinear>, // RGB444
fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB4444_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinear>, // RGBX8888
fetchTransformedBilinear<BlendTransformedBilinear>, // RGBA8888
fetchTransformedBilinear<BlendTransformedBilinear>, // RGBA8888_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinear>, // BGR30
fetchTransformedBilinear<BlendTransformedBilinear>, // A2BGR30_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinear>, // RGB30
fetchTransformedBilinear<BlendTransformedBilinear>, // A2RGB30_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinear>, // Alpha8
fetchTransformedBilinear<BlendTransformedBilinear>, // Grayscale8
},
{
0, // BilinearTiled
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // Mono
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // MonoLsb
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // Indexed8
fetchTransformedBilinearARGB32PM<BlendTransformedBilinearTiled>, // RGB32
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB32
fetchTransformedBilinearARGB32PM<BlendTransformedBilinearTiled>, // ARGB32_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB16
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB8565_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB666
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB6666_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB555
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB8555_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB888
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB444
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB4444_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGBX8888
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGBA8888
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGBA8888_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // BGR30
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // A2BGR30_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB30
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // A2RGB30_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // Alpha8
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // Grayscale8
},
// FetchUntransformed can have more specialized methods added depending on SIMD features.
static SourceFetchProc sourceFetchUntransformed[QImage::NImageFormats] = {
0, // Invalid
fetchUntransformed, // Mono
fetchUntransformed, // MonoLsb
fetchUntransformed, // Indexed8
fetchUntransformedARGB32PM, // RGB32
fetchUntransformed, // ARGB32
fetchUntransformedARGB32PM, // ARGB32_Premultiplied
fetchUntransformedRGB16, // RGB16
fetchUntransformed, // ARGB8565_Premultiplied
fetchUntransformed, // RGB666
fetchUntransformed, // ARGB6666_Premultiplied
fetchUntransformed, // RGB555
fetchUntransformed, // ARGB8555_Premultiplied
fetchUntransformed, // RGB888
fetchUntransformed, // RGB444
fetchUntransformed, // ARGB4444_Premultiplied
fetchUntransformed, // RGBX8888
fetchUntransformed, // RGBA8888
fetchUntransformed, // RGBA8888_Premultiplied
fetchUntransformed, // Format_BGR30
fetchUntransformed, // Format_A2BGR30_Premultiplied
fetchUntransformed, // Format_RGB30
fetchUntransformed, // Format_A2RGB30_Premultiplied
fetchUntransformed, // Alpha8
fetchUntransformed, // Grayscale8
};
static SourceFetchProc64 sourceFetch64[NBlendTypes][QImage::NImageFormats] = {
// Untransformed
{
0, // Invalid
fetchUntransformed64, // Mono
fetchUntransformed64, // MonoLsb
fetchUntransformed64, // Indexed8
fetchUntransformed64, // RGB32
fetchUntransformed64, // ARGB32
fetchUntransformed64, // ARGB32_Premultiplied
fetchUntransformed64, // RGB16
fetchUntransformed64, // ARGB8565_Premultiplied
fetchUntransformed64, // RGB666
fetchUntransformed64, // ARGB6666_Premultiplied
fetchUntransformed64, // RGB555
fetchUntransformed64, // ARGB8555_Premultiplied
fetchUntransformed64, // RGB888
fetchUntransformed64, // RGB444
fetchUntransformed64, // ARGB4444_Premultiplied
fetchUntransformed64, // RGBX8888
fetchUntransformed64, // RGBA8888
fetchUntransformed64, // RGBA8888_Premultiplied
fetchUntransformed64, // Format_BGR30
fetchUntransformed64, // Format_A2BGR30_Premultiplied
fetchUntransformed64, // Format_RGB30
fetchUntransformed64, // Format_A2RGB30_Premultiplied
fetchUntransformed64, // Alpha8
fetchUntransformed64, // Grayscale8
},
// Tiled
{
0, // Invalid
fetchUntransformed64, // Mono
fetchUntransformed64, // MonoLsb
fetchUntransformed64, // Indexed8
fetchUntransformed64, // RGB32
fetchUntransformed64, // ARGB32
fetchUntransformed64, // ARGB32_Premultiplied
fetchUntransformed64, // RGB16
fetchUntransformed64, // ARGB8565_Premultiplied
fetchUntransformed64, // RGB666
fetchUntransformed64, // ARGB6666_Premultiplied
fetchUntransformed64, // RGB555
fetchUntransformed64, // ARGB8555_Premultiplied
fetchUntransformed64, // RGB888
fetchUntransformed64, // RGB444
fetchUntransformed64, // ARGB4444_Premultiplied
fetchUntransformed64, // RGBX8888
fetchUntransformed64, // RGBA8888
fetchUntransformed64, // RGBA8888_Premultiplied
fetchUntransformed64, // BGR30
fetchUntransformed64, // A2BGR30_Premultiplied
fetchUntransformed64, // RGB30
fetchUntransformed64, // A2RGB30_Premultiplied
fetchUntransformed64, // Alpha8
fetchUntransformed64, // Grayscale8
},
// Transformed
{
0, // Invalid
fetchTransformed64<BlendTransformed>, // Mono
fetchTransformed64<BlendTransformed>, // MonoLsb
fetchTransformed64<BlendTransformed>, // Indexed8
fetchTransformed64<BlendTransformed>, // RGB32
fetchTransformed64<BlendTransformed>, // ARGB32
fetchTransformed64<BlendTransformed>, // ARGB32_Premultiplied
fetchTransformed64<BlendTransformed>, // RGB16
fetchTransformed64<BlendTransformed>, // ARGB8565_Premultiplied
fetchTransformed64<BlendTransformed>, // RGB666
fetchTransformed64<BlendTransformed>, // ARGB6666_Premultiplied
fetchTransformed64<BlendTransformed>, // RGB555
fetchTransformed64<BlendTransformed>, // ARGB8555_Premultiplied
fetchTransformed64<BlendTransformed>, // RGB888
fetchTransformed64<BlendTransformed>, // RGB444
fetchTransformed64<BlendTransformed>, // ARGB4444_Premultiplied
fetchTransformed64<BlendTransformed>, // RGBX8888
fetchTransformed64<BlendTransformed>, // RGBA8888
fetchTransformed64<BlendTransformed>, // RGBA8888_Premultiplied
fetchTransformed64<BlendTransformed>, // BGR30
fetchTransformed64<BlendTransformed>, // A2BGR30_Premultiplied
fetchTransformed64<BlendTransformed>, // RGB30
fetchTransformed64<BlendTransformed>, // A2RGB30_Premultiplied
fetchTransformed64<BlendTransformed>, // Alpah8
fetchTransformed64<BlendTransformed>, // Grayscale8
},
{
0, // TransformedTiled
fetchTransformed64<BlendTransformedTiled>, // Mono
fetchTransformed64<BlendTransformedTiled>, // MonoLsb
fetchTransformed64<BlendTransformedTiled>, // Indexed8
fetchTransformed64<BlendTransformedTiled>, // RGB32
fetchTransformed64<BlendTransformedTiled>, // ARGB32
fetchTransformed64<BlendTransformedTiled>, // ARGB32_Premultiplied
fetchTransformed64<BlendTransformedTiled>, // RGB16
fetchTransformed64<BlendTransformedTiled>, // ARGB8565_Premultiplied
fetchTransformed64<BlendTransformedTiled>, // RGB666
fetchTransformed64<BlendTransformedTiled>, // ARGB6666_Premultiplied
fetchTransformed64<BlendTransformedTiled>, // RGB555
fetchTransformed64<BlendTransformedTiled>, // ARGB8555_Premultiplied
fetchTransformed64<BlendTransformedTiled>, // RGB888
fetchTransformed64<BlendTransformedTiled>, // RGB444
fetchTransformed64<BlendTransformedTiled>, // ARGB4444_Premultiplied
fetchTransformed64<BlendTransformedTiled>, // RGBX8888
fetchTransformed64<BlendTransformedTiled>, // RGBA8888
fetchTransformed64<BlendTransformedTiled>, // RGBA8888_Premultiplied
fetchTransformed64<BlendTransformedTiled>, // BGR30
fetchTransformed64<BlendTransformedTiled>, // A2BGR30_Premultiplied
fetchTransformed64<BlendTransformedTiled>, // RGB30
fetchTransformed64<BlendTransformedTiled>, // A2RGB30_Premultiplied
fetchTransformed64<BlendTransformedTiled>, // Alpha8
fetchTransformed64<BlendTransformedTiled>, // Grayscale8
},
{
0, // Bilinear
fetchTransformedBilinear64<BlendTransformedBilinear>, // Mono
fetchTransformedBilinear64<BlendTransformedBilinear>, // MonoLsb
fetchTransformedBilinear64<BlendTransformedBilinear>, // Indexed8
fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB32
fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB32
fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB32_Premultiplied
fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB16
fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB8565_Premultiplied
fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB666
fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB6666_Premultiplied
fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB555
fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB8555_Premultiplied
fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB888
fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB444
fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB4444_Premultiplied
fetchTransformedBilinear64<BlendTransformedBilinear>, // RGBX8888
fetchTransformedBilinear64<BlendTransformedBilinear>, // RGBA8888
fetchTransformedBilinear64<BlendTransformedBilinear>, // RGBA8888_Premultiplied
fetchTransformedBilinear64<BlendTransformedBilinear>, // BGR30
fetchTransformedBilinear64<BlendTransformedBilinear>, // A2BGR30_Premultiplied
fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB30
fetchTransformedBilinear64<BlendTransformedBilinear>, // A2RGB30_Premultiplied
fetchTransformedBilinear64<BlendTransformedBilinear>, // Alpha8
fetchTransformedBilinear64<BlendTransformedBilinear>, // Grayscale8
},
{
0, // BilinearTiled
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // Mono
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // MonoLsb
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // Indexed8
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB32
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB32
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB32_Premultiplied
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB16
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB8565_Premultiplied
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB666
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB6666_Premultiplied
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB555
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB8555_Premultiplied
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB888
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB444
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB4444_Premultiplied
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGBX8888
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGBA8888
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGBA8888_Premultiplied
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // BGR30
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // A2BGR30_Premultiplied
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB30
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // A2RGB30_Premultiplied
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // Alpha8
fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // Grayscale8
},
static const SourceFetchProc sourceFetchGeneric[NBlendTypes] = {
fetchUntransformed, // Untransformed
fetchUntransformed, // Tiled
fetchTransformed<BlendTransformed>, // Transformed
fetchTransformed<BlendTransformedTiled>, // TransformedTiled
fetchTransformedBilinear<BlendTransformedBilinear>, // Bilinear
fetchTransformedBilinear<BlendTransformedBilinearTiled> // BilinearTiled
};
static SourceFetchProc sourceFetchARGB32PM[NBlendTypes] = {
fetchUntransformedARGB32PM, // Untransformed
fetchUntransformedARGB32PM, // Tiled
fetchTransformedARGB32PM<BlendTransformed>, // Transformed
fetchTransformedARGB32PM<BlendTransformedTiled>, // TransformedTiled
fetchTransformedBilinearARGB32PM<BlendTransformedBilinear>, // Bilinear
fetchTransformedBilinearARGB32PM<BlendTransformedBilinearTiled> // BilinearTiled
};
static const SourceFetchProc64 sourceFetchGeneric64[NBlendTypes] = {
fetchUntransformed64, // Untransformed
fetchUntransformed64, // Tiled
fetchTransformed64<BlendTransformed>, // Transformed
fetchTransformed64<BlendTransformedTiled>, // TransformedTiled
fetchTransformedBilinear64<BlendTransformedBilinear>, // Bilinear
fetchTransformedBilinear64<BlendTransformedBilinearTiled> // BilinearTiled
};
static inline SourceFetchProc getSourceFetch(TextureBlendType blendType, QImage::Format format)
{
if (format == QImage::Format_RGB32 || format == QImage::Format_ARGB32_Premultiplied)
return sourceFetchARGB32PM[blendType];
if (blendType == BlendUntransformed || blendType == BlendTiled)
return sourceFetchUntransformed[format];
return sourceFetchGeneric[blendType];
}
#define FIXPT_BITS 8
#define FIXPT_SIZE (1<<FIXPT_BITS)
@ -3939,8 +3669,8 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in
break;
case QSpanData::Texture:
solidSource = !data->texture.hasAlpha;
op.srcFetch = sourceFetch[getBlendType(data)][data->texture.format];
op.srcFetch64 = sourceFetch64[getBlendType(data)][data->texture.format];
op.srcFetch = getSourceFetch(getBlendType(data), data->texture.format);
op.srcFetch64 = sourceFetchGeneric64[getBlendType(data)];
break;
default:
Q_UNREACHABLE();
@ -5483,181 +5213,67 @@ static void blend_transformed_tiled_rgb565(int count, const QSpan *spans, void *
/* Image formats here are target formats */
static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats] = {
// Untransformed
{
0, // Invalid
blend_untransformed_generic, // Mono
blend_untransformed_generic, // MonoLsb
blend_untransformed_generic, // Indexed8
blend_untransformed_generic, // RGB32
blend_untransformed_generic, // ARGB32
blend_untransformed_argb, // ARGB32_Premultiplied
blend_untransformed_rgb565,
blend_untransformed_generic,
blend_untransformed_generic,
blend_untransformed_generic,
blend_untransformed_generic,
blend_untransformed_generic,
blend_untransformed_generic,
blend_untransformed_generic,
blend_untransformed_generic,
blend_untransformed_generic,
blend_untransformed_generic,
blend_untransformed_generic,
blend_untransformed_generic_rgb64,
blend_untransformed_generic_rgb64,
blend_untransformed_generic_rgb64,
blend_untransformed_generic_rgb64,
blend_untransformed_generic,
blend_untransformed_generic,
},
// Tiled
{
0, // Invalid
blend_tiled_generic, // Mono
blend_tiled_generic, // MonoLsb
blend_tiled_generic, // Indexed8
blend_tiled_generic, // RGB32
blend_tiled_generic, // ARGB32
blend_tiled_argb, // ARGB32_Premultiplied
blend_tiled_rgb565,
blend_tiled_generic,
blend_tiled_generic,
blend_tiled_generic,
blend_tiled_generic,
blend_tiled_generic,
blend_tiled_generic,
blend_tiled_generic,
blend_tiled_generic,
blend_tiled_generic,
blend_tiled_generic,
blend_tiled_generic,
blend_tiled_generic_rgb64,
blend_tiled_generic_rgb64,
blend_tiled_generic_rgb64,
blend_tiled_generic_rgb64,
blend_tiled_generic,
blend_tiled_generic,
},
// Transformed
{
0, // Invalid
blend_src_generic, // Mono
blend_src_generic, // MonoLsb
blend_src_generic, // Indexed8
blend_src_generic, // RGB32
blend_src_generic, // ARGB32
blend_transformed_argb, // ARGB32_Premultiplied
blend_transformed_rgb565,
blend_src_generic, // ARGB8565_Premultiplied
blend_src_generic, // RGB666
blend_src_generic, // ARGB6666_Premultiplied
blend_src_generic, // RGB555
blend_src_generic, // ARGB8555_Premultiplied
blend_src_generic, // RGB888
blend_src_generic, // RGB444
blend_src_generic, // ARGB4444_Premultiplied
blend_src_generic, // RGBX8888
blend_src_generic, // RGBA8888
blend_src_generic, // RGBA8888_Premultiplied
blend_src_generic_rgb64,
blend_src_generic_rgb64,
blend_src_generic_rgb64,
blend_src_generic_rgb64,
blend_src_generic,
blend_src_generic,
},
// TransformedTiled
{
0,
blend_src_generic, // Mono
blend_src_generic, // MonoLsb
blend_src_generic, // Indexed8
blend_src_generic, // RGB32
blend_src_generic, // ARGB32
blend_transformed_tiled_argb, // ARGB32_Premultiplied
blend_transformed_tiled_rgb565,
blend_src_generic, // ARGB8565_Premultiplied
blend_src_generic, // RGB666
blend_src_generic, // ARGB6666_Premultiplied
blend_src_generic, // RGB555
blend_src_generic, // ARGB8555_Premultiplied
blend_src_generic, // RGB888
blend_src_generic, // RGB444
blend_src_generic, // ARGB4444_Premultiplied
blend_src_generic, // RGBX8888
blend_src_generic, // RGBA8888
blend_src_generic, // RGBA8888_Premultiplied
blend_src_generic_rgb64,
blend_src_generic_rgb64,
blend_src_generic_rgb64,
blend_src_generic_rgb64,
blend_src_generic,
blend_src_generic,
},
// Bilinear
{
0,
blend_src_generic, // Mono
blend_src_generic, // MonoLsb
blend_src_generic, // Indexed8
blend_src_generic, // RGB32
blend_src_generic, // ARGB32
blend_src_generic, // ARGB32_Premultiplied
blend_transformed_bilinear_rgb565,
blend_src_generic, // ARGB8565_Premultiplied
blend_src_generic, // RGB666
blend_src_generic, // ARGB6666_Premultiplied
blend_src_generic, // RGB555
blend_src_generic, // ARGB8555_Premultiplied
blend_src_generic, // RGB888
blend_src_generic, // RGB444
blend_src_generic, // ARGB4444_Premultiplied
blend_src_generic, // RGBX8888
blend_src_generic, // RGBA8888
blend_src_generic, // RGBA8888_Premultiplied
blend_src_generic_rgb64,
blend_src_generic_rgb64,
blend_src_generic_rgb64,
blend_src_generic_rgb64,
blend_src_generic,
blend_src_generic,
},
// BilinearTiled
{
0,
blend_src_generic, // Mono
blend_src_generic, // MonoLsb
blend_src_generic, // Indexed8
blend_src_generic, // RGB32
blend_src_generic, // ARGB32
blend_src_generic, // ARGB32_Premultiplied
blend_src_generic, // RGB16
blend_src_generic, // ARGB8565_Premultiplied
blend_src_generic, // RGB666
blend_src_generic, // ARGB6666_Premultiplied
blend_src_generic, // RGB555
blend_src_generic, // ARGB8555_Premultiplied
blend_src_generic, // RGB888
blend_src_generic, // RGB444
blend_src_generic, // ARGB4444_Premultiplied
blend_src_generic, // RGBX8888
blend_src_generic, // RGBA8888
blend_src_generic, // RGBA8888_Premultiplied
blend_src_generic_rgb64, // BGR30
blend_src_generic_rgb64, // A2BGR30_Premultiplied
blend_src_generic_rgb64, // RGB30
blend_src_generic_rgb64, // A2RGB30_Premultiplied
blend_src_generic, // Alpha8
blend_src_generic, // Grayscale8
}
static const ProcessSpans processTextureSpansARGB32PM[NBlendTypes] = {
blend_untransformed_argb, // Untransformed
blend_tiled_argb, // Tiled
blend_transformed_argb, // Transformed
blend_transformed_tiled_argb, // TransformedTiled
blend_src_generic, // TransformedBilinear
blend_src_generic // TransformedBilinearTiled
};
static const ProcessSpans processTextureSpansRGB16[NBlendTypes] = {
blend_untransformed_rgb565, // Untransformed
blend_tiled_rgb565, // Tiled
blend_transformed_rgb565, // Transformed
blend_transformed_tiled_rgb565, // TransformedTiled
blend_transformed_bilinear_rgb565, // TransformedBilinear
blend_src_generic // TransformedBilinearTiled
};
static const ProcessSpans processTextureSpansGeneric[NBlendTypes] = {
blend_untransformed_generic, // Untransformed
blend_tiled_generic, // Tiled
blend_src_generic, // Transformed
blend_src_generic, // TransformedTiled
blend_src_generic, // TransformedBilinear
blend_src_generic // TransformedBilinearTiled
};
static const ProcessSpans processTextureSpansGeneric64[NBlendTypes] = {
blend_untransformed_generic_rgb64, // Untransformed
blend_tiled_generic_rgb64, // Tiled
blend_src_generic_rgb64, // Transformed
blend_src_generic_rgb64, // TransformedTiled
blend_src_generic_rgb64, // TransformedBilinear
blend_src_generic_rgb64 // TransformedBilinearTiled
};
void qBlendTexture(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
ProcessSpans proc = processTextureSpans[getBlendType(data)][data->rasterBuffer->format];
TextureBlendType blendType = getBlendType(data);
ProcessSpans proc;
switch (data->rasterBuffer->format) {
case QImage::Format_ARGB32_Premultiplied:
proc = processTextureSpansARGB32PM[blendType];
break;
case QImage::Format_RGB16:
proc = processTextureSpansRGB16[blendType];
break;
case QImage::Format_BGR30:
case QImage::Format_A2BGR30_Premultiplied:
case QImage::Format_RGB30:
case QImage::Format_A2RGB30_Premultiplied:
proc = processTextureSpansGeneric64[blendType];
break;
case QImage::Format_Invalid:
Q_UNREACHABLE();
return;
default:
proc = processTextureSpansGeneric[blendType];
break;
}
proc(count, spans, userData);
}
@ -6548,6 +6164,15 @@ static void qInitDrawhelperFunctions()
qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2;
extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha);
extern void QT_FASTCALL comp_func_Source_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
extern void QT_FASTCALL comp_func_Plus_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_sse2;
qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_sse2;
qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_sse2;
qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2;
#ifdef QT_COMPILER_SUPPORTS_SSSE3
if (qCpuHasFeature(SSSE3)) {
extern void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl,
@ -6563,8 +6188,7 @@ static void qInitDrawhelperFunctions()
qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qStorePixels[QPixelLayout::BPP24] = storePixelsBPP24_ssse3;
sourceFetch[BlendUntransformed][QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3;
sourceFetch[BlendTiled][QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3;
sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3;
}
#endif // SSSE3
@ -6592,24 +6216,39 @@ static void qInitDrawhelperFunctions()
}
#endif
#if defined(QT_COMPILER_SUPPORTS_AVX2) && !defined(__AVX2__)
#if defined(QT_COMPILER_SUPPORTS_AVX2)
if (qCpuHasFeature(AVX2)) {
#if !defined(__AVX2__)
extern const uint *QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *);
extern const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *);
qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_avx2;
qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_avx2;
#endif
extern void qt_blend_rgb32_on_rgb32_avx2(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
int w, int h, int const_alpha);
extern void qt_blend_argb32_on_argb32_avx2(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
int w, int h, int const_alpha);
qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx2;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx2;
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx2;
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx2;
qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
extern void QT_FASTCALL comp_func_SourceOver_avx2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
extern void QT_FASTCALL comp_func_solid_SourceOver_avx2(uint *destPixels, int length, uint color, uint const_alpha);
extern void QT_FASTCALL comp_func_Source_avx2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_avx2;
qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_avx2;
qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_avx2;
}
#endif
extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha);
extern void QT_FASTCALL comp_func_Source_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
extern void QT_FASTCALL comp_func_Plus_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_sse2;
qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_sse2;
qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_sse2;
qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2;
#endif // SSE2
@ -6634,8 +6273,7 @@ static void qInitDrawhelperFunctions()
qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon;
sourceFetch[BlendUntransformed][QImage::Format_RGB888] = qt_fetchUntransformed_888_neon;
sourceFetch[BlendTiled][QImage::Format_RGB888] = qt_fetchUntransformed_888_neon;
sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_neon;
#if defined(ENABLE_PIXMAN_DRAWHELPERS)
// The RGB16 helpers are using Arm32 assemblythat has not been ported to AArch64
@ -6696,14 +6334,9 @@ static void qInitDrawhelperFunctions()
destStoreProc[QImage::Format_ARGB32] = qt_destStoreARGB32_mips_dsp;
sourceFetch[BlendUntransformed][QImage::Format_RGB888] = qt_fetchUntransformed_888_mips_dsp;
sourceFetch[BlendTiled][QImage::Format_RGB888] = qt_fetchUntransformed_888_mips_dsp;
sourceFetch[BlendUntransformed][QImage::Format_RGB444] = qt_fetchUntransformed_444_mips_dsp;
sourceFetch[BlendTiled][QImage::Format_RGB444] = qt_fetchUntransformed_444_mips_dsp;
sourceFetch[BlendUntransformed][QImage::Format_ARGB8565_Premultiplied] = qt_fetchUntransformed_argb8565_premultiplied_mips_dsp;
sourceFetch[BlendTiled][QImage::Format_ARGB8565_Premultiplied] = qt_fetchUntransformed_argb8565_premultiplied_mips_dsp;
sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_mips_dsp;
sourceFetchUntransformed[QImage::Format_RGB444] = qt_fetchUntransformed_444_mips_dsp;
sourceFetchUntransformed[QImage::Format_ARGB8565_Premultiplied] = qt_fetchUntransformed_argb8565_premultiplied_mips_dsp;
#if defined(QT_COMPILER_SUPPORTS_MIPS_DSPR2)
qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_mips_dspr2;

View File

@ -37,12 +37,14 @@
**
****************************************************************************/
#include <private/qdrawhelper_p.h>
#include "qdrawhelper_p.h"
#include "qdrawingprimitive_sse2_p.h"
#if defined(QT_COMPILER_SUPPORTS_AVX2)
QT_BEGIN_NAMESPACE
// Autovectorized premultiply functions:
const uint *QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
{
@ -55,6 +57,307 @@ const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, const uint
return qt_convertRGBA8888ToARGB32PM(buffer, src, count);
}
// Vectorized blend functions:
// See BYTE_MUL_SSE2 for details.
inline static void BYTE_MUL_AVX2(__m256i &pixelVector, const __m256i &alphaChannel, const __m256i &colorMask, const __m256i &half)
{
__m256i pixelVectorAG = _mm256_srli_epi16(pixelVector, 8);
__m256i pixelVectorRB = _mm256_and_si256(pixelVector, colorMask);
pixelVectorAG = _mm256_mullo_epi16(pixelVectorAG, alphaChannel);
pixelVectorRB = _mm256_mullo_epi16(pixelVectorRB, alphaChannel);
pixelVectorRB = _mm256_add_epi16(pixelVectorRB, _mm256_srli_epi16(pixelVectorRB, 8));
pixelVectorAG = _mm256_add_epi16(pixelVectorAG, _mm256_srli_epi16(pixelVectorAG, 8));
pixelVectorRB = _mm256_add_epi16(pixelVectorRB, half);
pixelVectorAG = _mm256_add_epi16(pixelVectorAG, half);
pixelVectorRB = _mm256_srli_epi16(pixelVectorRB, 8);
pixelVectorAG = _mm256_andnot_si256(colorMask, pixelVectorAG);
pixelVector = _mm256_or_si256(pixelVectorAG, pixelVectorRB);
}
// See INTERPOLATE_PIXEL_255_SSE2 for details.
inline static void INTERPOLATE_PIXEL_255_AVX2(const __m256i &srcVector, __m256i &dstVector, const __m256i &alphaChannel, const __m256i &oneMinusAlphaChannel, const __m256i &colorMask, const __m256i &half)
{
const __m256i srcVectorAG = _mm256_srli_epi16(srcVector, 8);
const __m256i dstVectorAG = _mm256_srli_epi16(dstVector, 8);
const __m256i srcVectorRB = _mm256_and_si256(srcVector, colorMask);
const __m256i dstVectorRB = _mm256_and_si256(dstVector, colorMask);
const __m256i srcVectorAGalpha = _mm256_mullo_epi16(srcVectorAG, alphaChannel);
const __m256i srcVectorRBalpha = _mm256_mullo_epi16(srcVectorRB, alphaChannel);
const __m256i dstVectorAGoneMinusAlpha = _mm256_mullo_epi16(dstVectorAG, oneMinusAlphaChannel);
const __m256i dstVectorRBoneMinusAlpha = _mm256_mullo_epi16(dstVectorRB, oneMinusAlphaChannel);
__m256i finalAG = _mm256_add_epi16(srcVectorAGalpha, dstVectorAGoneMinusAlpha);
__m256i finalRB = _mm256_add_epi16(srcVectorRBalpha, dstVectorRBoneMinusAlpha);
finalAG = _mm256_add_epi16(finalAG, _mm256_srli_epi16(finalAG, 8));
finalRB = _mm256_add_epi16(finalRB, _mm256_srli_epi16(finalRB, 8));
finalAG = _mm256_add_epi16(finalAG, half);
finalRB = _mm256_add_epi16(finalRB, half);
finalAG = _mm256_andnot_si256(colorMask, finalAG);
finalRB = _mm256_srli_epi16(finalRB, 8);
dstVector = _mm256_or_si256(finalAG, finalRB);
}
// See BLEND_SOURCE_OVER_ARGB32_SSE2 for details.
inline static void BLEND_SOURCE_OVER_ARGB32_AVX2(quint32 *dst, const quint32 *src, const int length)
{
const __m256i half = _mm256_set1_epi16(0x80);
const __m256i one = _mm256_set1_epi16(0xff);
const __m256i colorMask = _mm256_set1_epi32(0x00ff00ff);
const __m256i alphaMask = _mm256_set1_epi32(0xff000000);
const __m256i offsetMask = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7);
const __m256i alphaShuffleMask = _mm256_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3,
char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3);
const int minusOffsetToAlignDstOn32Bytes = (reinterpret_cast<quintptr>(dst) >> 2) & 0x7;
int x = 0;
// Prologue to handle all pixels until dst is 32-byte aligned in one step.
if (minusOffsetToAlignDstOn32Bytes != 0 && x < (length - 7)) {
const __m256i prologueMask = _mm256_sub_epi32(_mm256_set1_epi32(minusOffsetToAlignDstOn32Bytes - 1), offsetMask);
const __m256i srcVector = _mm256_maskload_epi32((const int *)&src[x - minusOffsetToAlignDstOn32Bytes], prologueMask);
const __m256i prologueAlphaMask = _mm256_blendv_epi8(_mm256_setzero_si256(), alphaMask, prologueMask);
if (!_mm256_testz_si256(srcVector, prologueAlphaMask)) {
if (_mm256_testc_si256(srcVector, prologueAlphaMask)) {
_mm256_maskstore_epi32((int *)&dst[x - minusOffsetToAlignDstOn32Bytes], prologueMask, srcVector);
} else {
__m256i alphaChannel = _mm256_shuffle_epi8(srcVector, alphaShuffleMask);
alphaChannel = _mm256_sub_epi16(one, alphaChannel);
__m256i dstVector = _mm256_maskload_epi32((int *)&dst[x - minusOffsetToAlignDstOn32Bytes], prologueMask);
BYTE_MUL_AVX2(dstVector, alphaChannel, colorMask, half);
dstVector = _mm256_add_epi8(dstVector, srcVector);
_mm256_maskstore_epi32((int *)&dst[x - minusOffsetToAlignDstOn32Bytes], prologueMask, dstVector);
}
}
x += (8 - minusOffsetToAlignDstOn32Bytes);
}
for (; x < (length - 7); x += 8) {
const __m256i srcVector = _mm256_lddqu_si256((const __m256i *)&src[x]);
if (!_mm256_testz_si256(srcVector, alphaMask)) {
if (_mm256_testc_si256(srcVector, alphaMask)) {
_mm256_store_si256((__m256i *)&dst[x], srcVector);
} else {
__m256i alphaChannel = _mm256_shuffle_epi8(srcVector, alphaShuffleMask);
alphaChannel = _mm256_sub_epi16(one, alphaChannel);
__m256i dstVector = _mm256_load_si256((__m256i *)&dst[x]);
BYTE_MUL_AVX2(dstVector, alphaChannel, colorMask, half);
dstVector = _mm256_add_epi8(dstVector, srcVector);
_mm256_store_si256((__m256i *)&dst[x], dstVector);
}
}
}
// Epilogue to handle all remaining pixels in one step.
if (x < length) {
const __m256i epilogueMask = _mm256_add_epi32(offsetMask, _mm256_set1_epi32(x - length));
const __m256i srcVector = _mm256_maskload_epi32((const int *)&src[x], epilogueMask);
const __m256i epilogueAlphaMask = _mm256_blendv_epi8(_mm256_setzero_si256(), alphaMask, epilogueMask);
if (!_mm256_testz_si256(srcVector, epilogueAlphaMask)) {
if (_mm256_testc_si256(srcVector, epilogueAlphaMask)) {
_mm256_maskstore_epi32((int *)&dst[x], epilogueMask, srcVector);
} else {
__m256i alphaChannel = _mm256_shuffle_epi8(srcVector, alphaShuffleMask);
alphaChannel = _mm256_sub_epi16(one, alphaChannel);
__m256i dstVector = _mm256_maskload_epi32((int *)&dst[x], epilogueMask);
BYTE_MUL_AVX2(dstVector, alphaChannel, colorMask, half);
dstVector = _mm256_add_epi8(dstVector, srcVector);
_mm256_maskstore_epi32((int *)&dst[x], epilogueMask, dstVector);
}
}
}
}
// See BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_SSE2 for details.
inline static void BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_AVX2(quint32 *dst, const quint32 *src, const int length, const int const_alpha)
{
int x = 0;
ALIGNMENT_PROLOGUE_32BYTES(dst, x, length)
blend_pixel(dst[x], src[x], const_alpha);
const __m256i half = _mm256_set1_epi16(0x80);
const __m256i one = _mm256_set1_epi16(0xff);
const __m256i colorMask = _mm256_set1_epi32(0x00ff00ff);
const __m256i alphaMask = _mm256_set1_epi32(0xff000000);
const __m256i alphaShuffleMask = _mm256_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3,
char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3);
const __m256i constAlphaVector = _mm256_set1_epi16(const_alpha);
for (; x < (length - 7); x += 8) {
__m256i srcVector = _mm256_lddqu_si256((const __m256i *)&src[x]);
if (!_mm256_testz_si256(srcVector, alphaMask)) {
BYTE_MUL_AVX2(srcVector, constAlphaVector, colorMask, half);
__m256i alphaChannel = _mm256_shuffle_epi8(srcVector, alphaShuffleMask);
alphaChannel = _mm256_sub_epi16(one, alphaChannel);
__m256i dstVector = _mm256_load_si256((__m256i *)&dst[x]);
BYTE_MUL_AVX2(dstVector, alphaChannel, colorMask, half);
dstVector = _mm256_add_epi8(dstVector, srcVector);
_mm256_store_si256((__m256i *)&dst[x], dstVector);
}
}
for (; x < length; ++x)
blend_pixel(dst[x], src[x], const_alpha);
}
void qt_blend_argb32_on_argb32_avx2(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
int w, int h,
int const_alpha)
{
if (const_alpha == 256) {
for (int y = 0; y < h; ++y) {
const quint32 *src = reinterpret_cast<const quint32 *>(srcPixels);
quint32 *dst = reinterpret_cast<quint32 *>(destPixels);
BLEND_SOURCE_OVER_ARGB32_AVX2(dst, src, w);
destPixels += dbpl;
srcPixels += sbpl;
}
} else if (const_alpha != 0) {
const_alpha = (const_alpha * 255) >> 8;
for (int y = 0; y < h; ++y) {
const quint32 *src = reinterpret_cast<const quint32 *>(srcPixels);
quint32 *dst = reinterpret_cast<quint32 *>(destPixels);
BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_AVX2(dst, src, w, const_alpha);
destPixels += dbpl;
srcPixels += sbpl;
}
}
}
void qt_blend_rgb32_on_rgb32_avx2(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
int w, int h,
int const_alpha)
{
if (const_alpha == 256) {
for (int y = 0; y < h; ++y) {
const quint32 *src = reinterpret_cast<const quint32 *>(srcPixels);
quint32 *dst = reinterpret_cast<quint32 *>(destPixels);
::memcpy(dst, src, w * sizeof(uint));
srcPixels += sbpl;
destPixels += dbpl;
}
return;
}
if (const_alpha == 0)
return;
const __m256i half = _mm256_set1_epi16(0x80);
const __m256i colorMask = _mm256_set1_epi32(0x00ff00ff);
const_alpha = (const_alpha * 255) >> 8;
int one_minus_const_alpha = 255 - const_alpha;
const __m256i constAlphaVector = _mm256_set1_epi16(const_alpha);
const __m256i oneMinusConstAlpha = _mm256_set1_epi16(one_minus_const_alpha);
for (int y = 0; y < h; ++y) {
const quint32 *src = reinterpret_cast<const quint32 *>(srcPixels);
quint32 *dst = reinterpret_cast<quint32 *>(destPixels);
int x = 0;
// First, align dest to 32 bytes:
ALIGNMENT_PROLOGUE_32BYTES(dst, x, w)
dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha);
// 2) interpolate pixels with AVX2
for (; x < (w - 7); x += 8) {
const __m256i srcVector = _mm256_lddqu_si256((const __m256i *)&src[x]);
if (!_mm256_testc_si256(srcVector, _mm256_setzero_si256())) {
__m256i dstVector = _mm256_load_si256((__m256i *)&dst[x]);
INTERPOLATE_PIXEL_255_AVX2(srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half);
_mm256_store_si256((__m256i *)&dst[x], dstVector);
}
}
// 3) Epilogue
for (; x < w; ++x)
dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha);
srcPixels += sbpl;
destPixels += dbpl;
}
}
void QT_FASTCALL comp_func_SourceOver_avx2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha)
{
Q_ASSERT(const_alpha < 256);
const quint32 *src = (const quint32 *) srcPixels;
quint32 *dst = (quint32 *) destPixels;
if (const_alpha == 255)
BLEND_SOURCE_OVER_ARGB32_AVX2(dst, src, length);
else
BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_AVX2(dst, src, length, const_alpha);
}
void QT_FASTCALL comp_func_Source_avx2(uint *dst, const uint *src, int length, uint const_alpha)
{
if (const_alpha == 255) {
::memcpy(dst, src, length * sizeof(uint));
} else {
const int ialpha = 255 - const_alpha;
int x = 0;
// 1) prologue, align on 32 bytes
ALIGNMENT_PROLOGUE_32BYTES(dst, x, length)
dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], ialpha);
// 2) interpolate pixels with AVX2
const __m256i half = _mm256_set1_epi16(0x80);
const __m256i colorMask = _mm256_set1_epi32(0x00ff00ff);
const __m256i constAlphaVector = _mm256_set1_epi16(const_alpha);
const __m256i oneMinusConstAlpha = _mm256_set1_epi16(ialpha);
for (; x < length - 7; x += 8) {
const __m256i srcVector = _mm256_lddqu_si256((const __m256i *)&src[x]);
__m256i dstVector = _mm256_load_si256((__m256i *)&dst[x]);
INTERPOLATE_PIXEL_255_AVX2(srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half);
_mm256_store_si256((__m256i *)&dst[x], dstVector);
}
// 3) Epilogue
for (; x < length; ++x)
dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], ialpha);
}
}
void QT_FASTCALL comp_func_solid_SourceOver_avx2(uint *destPixels, int length, uint color, uint const_alpha)
{
if ((const_alpha & qAlpha(color)) == 255) {
qt_memfill32(destPixels, color, length);
} else {
if (const_alpha != 255)
color = BYTE_MUL(color, const_alpha);
const quint32 minusAlphaOfColor = qAlpha(~color);
int x = 0;
quint32 *dst = (quint32 *) destPixels;
const __m256i colorVector = _mm256_set1_epi32(color);
const __m256i colorMask = _mm256_set1_epi32(0x00ff00ff);
const __m256i half = _mm256_set1_epi16(0x80);
const __m256i minusAlphaOfColorVector = _mm256_set1_epi16(minusAlphaOfColor);
ALIGNMENT_PROLOGUE_32BYTES(dst, x, length)
destPixels[x] = color + BYTE_MUL(destPixels[x], minusAlphaOfColor);
for (; x < length - 7; x += 8) {
__m256i dstVector = _mm256_load_si256((__m256i *)&dst[x]);
BYTE_MUL_AVX2(dstVector, minusAlphaOfColorVector, colorMask, half);
dstVector = _mm256_add_epi8(colorVector, dstVector);
_mm256_store_si256((__m256i *)&dst[x], dstVector);
}
for (; x < length; ++x)
destPixels[x] = color + BYTE_MUL(destPixels[x], minusAlphaOfColor);
}
}
QT_END_NAMESPACE
#endif

View File

@ -118,6 +118,11 @@ public:
virtual void systemStateChanged() { }
void drawBoxTextItem(const QPointF &p, const QTextItemInt &ti);
static QPaintEnginePrivate *get(QPaintEngine *paintEngine) { return paintEngine->d_func(); }
virtual QPaintEngine *aggregateEngine() { return 0; }
virtual Qt::HANDLE nativeHandle() { return 0; }
};
QT_END_NAMESPACE

View File

@ -2439,7 +2439,7 @@ int QFontDatabasePrivate::addAppFont(const QByteArray &fontData, const QString &
}
if (font.fileName.isEmpty() && !fontData.isEmpty())
font.fileName = QString::fromLatin1(":qmemoryfonts/") + QString::number(i);
font.fileName = QLatin1String(":qmemoryfonts/") + QString::number(i);
registerFont(&font);
if (font.families.isEmpty())

View File

@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE
static QString pixelToPoint(qreal pixels)
{
// we hardcode 96 DPI, we do the same in the ODF importer to have a perfect roundtrip.
return QString::number(pixels * 72 / 96) + QString::fromLatin1("pt");
return QString::number(pixels * 72 / 96) + QLatin1String("pt");
}
// strategies

View File

@ -319,9 +319,9 @@ void QHttpNetworkConnectionPrivate::prepareRequest(HttpMessagePair &messagePair)
if (systemLocale == QLatin1String("C"))
acceptLanguage = QString::fromLatin1("en,*");
else if (systemLocale.startsWith(QLatin1String("en-")))
acceptLanguage = QString::fromLatin1("%1,*").arg(systemLocale);
acceptLanguage = systemLocale + QLatin1String(",*");
else
acceptLanguage = QString::fromLatin1("%1,en,*").arg(systemLocale);
acceptLanguage = systemLocale + QLatin1String(",en,*");
request.setHeaderField("Accept-Language", acceptLanguage.toLatin1());
}

View File

@ -87,10 +87,10 @@ public:
BackgroundRequestAttribute,
SpdyAllowedAttribute,
SpdyWasUsedAttribute,
HTTP2AllowedAttribute,
HTTP2WasUsedAttribute,
EmitAllUploadProgressSignalsAttribute,
FollowRedirectsAttribute,
HTTP2AllowedAttribute,
HTTP2WasUsedAttribute,
OriginalContentLengthAttribute,
User = 1000,

View File

@ -488,7 +488,7 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
interfaces = createInterfaces(interfaceListing);
for (ifaddrs *ptr = interfaceListing; ptr; ptr = ptr->ifa_next) {
// Find the interface
QString name = QString::fromLatin1(ptr->ifa_name);
QLatin1String name(ptr->ifa_name);
QNetworkInterfacePrivate *iface = 0;
QList<QNetworkInterfacePrivate *>::Iterator if_it = interfaces.begin();
for ( ; if_it != interfaces.end(); ++if_it)

View File

@ -79,7 +79,7 @@ static bool ignoreProxyFor(const QNetworkProxyQuery &query)
if (!peerHostName.startsWith('.'))
peerHostName.prepend('.');
if (peerHostName.endsWith(QString::fromLatin1(token)))
if (peerHostName.endsWith(QLatin1String(token)))
return true;
}

View File

@ -135,7 +135,7 @@ bool QDeviceDiscoveryStatic::checkDeviceType(const QString &device)
qCDebug(lcDD) << "doing static device discovery for " << device;
if ((m_types & Device_DRM) && device.contains(QString::fromLatin1(QT_DRM_DEVICE_PREFIX))) {
if ((m_types & Device_DRM) && device.contains(QLatin1String(QT_DRM_DEVICE_PREFIX))) {
QT_CLOSE(fd);
return true;
}

View File

@ -62,13 +62,20 @@ void QRasterBackingStore::resize(const QSize &size, const QRegion &staticContent
if (m_image.size() == effectiveBufferSize)
return;
QImage::Format format = window()->format().hasAlpha() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
m_image = QImage(effectiveBufferSize, format);
m_image = QImage(effectiveBufferSize, format());
m_image.setDevicePixelRatio(windowDevicePixelRatio);
if (format == QImage::Format_ARGB32_Premultiplied)
if (m_image.format() == QImage::Format_ARGB32_Premultiplied)
m_image.fill(Qt::transparent);
}
QImage::Format QRasterBackingStore::format() const
{
if (window()->format().hasAlpha())
return QImage::Format_ARGB32_Premultiplied;
else
return QImage::Format_RGB32;
}
QPaintDevice *QRasterBackingStore::paintDevice()
{
return &m_image;

View File

@ -62,13 +62,16 @@ public:
QRasterBackingStore(QWindow *window);
~QRasterBackingStore();
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
QImage toImage() const Q_DECL_OVERRIDE;
void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE;
void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE;
bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
void beginPaint(const QRegion &region) Q_DECL_OVERRIDE;
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
QImage toImage() const Q_DECL_OVERRIDE;
protected:
virtual QImage::Format format() const;
QImage m_image;
};

View File

@ -29,6 +29,6 @@ unix:!darwin:qtConfig(dbus) {
include(dbusmenu/dbusmenu.pri)
include(dbustray/dbustray.pri)
}
uikit: include(graphics/graphics.pri)
darwin: include(graphics/graphics.pri)
load(qt_module)

View File

@ -40,33 +40,20 @@
#ifndef QBACKINGSTORE_COCOA_H
#define QBACKINGSTORE_COCOA_H
#include <AppKit/AppKit.h>
#include "qcocoawindow.h"
#include "qnsview.h"
#include <qpa/qplatformbackingstore.h>
#include <QtPlatformSupport/private/qrasterbackingstore_p.h>
QT_BEGIN_NAMESPACE
class QCocoaBackingStore : public QPlatformBackingStore
class QCocoaBackingStore : public QRasterBackingStore
{
public:
QCocoaBackingStore(QWindow *window);
~QCocoaBackingStore();
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
void flush(QWindow *widget, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
QImage toImage() const Q_DECL_OVERRIDE;
void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE;
bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
void beginPaint(const QRegion &region) Q_DECL_OVERRIDE;
qreal getBackingStoreDevicePixelRatio();
void flush(QWindow *, const QRegion &, const QPoint &) Q_DECL_OVERRIDE;
private:
QImage m_qImage;
QSize m_requestedSize;
QImage::Format format() const Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE

View File

@ -38,13 +38,13 @@
****************************************************************************/
#include "qcocoabackingstore.h"
#include <QtGui/QPainter>
#include "qcocoahelpers.h"
#include "qcocoawindow.h"
QT_BEGIN_NAMESPACE
QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
: QPlatformBackingStore(window)
: QRasterBackingStore(window)
{
}
@ -54,69 +54,21 @@ QCocoaBackingStore::~QCocoaBackingStore()
[cocoaWindow->m_qtView clearBackingStore:this];
}
QPaintDevice *QCocoaBackingStore::paintDevice()
QImage::Format QCocoaBackingStore::format() const
{
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle());
int windowDevicePixelRatio = int(cocoaWindow->devicePixelRatio());
if (static_cast<QCocoaWindow *>(window()->handle())->m_drawContentBorderGradient)
return QImage::Format_ARGB32_Premultiplied;
// Receate the backing store buffer if the effective buffer size has changed,
// either due to a window resize or devicePixelRatio change.
QSize effectiveBufferSize = m_requestedSize * windowDevicePixelRatio;
if (m_qImage.size() != effectiveBufferSize) {
QImage::Format format = (window()->format().hasAlpha() || cocoaWindow->m_drawContentBorderGradient)
? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
m_qImage = QImage(effectiveBufferSize, format);
m_qImage.setDevicePixelRatio(windowDevicePixelRatio);
if (format == QImage::Format_ARGB32_Premultiplied)
m_qImage.fill(Qt::transparent);
}
return &m_qImage;
return QRasterBackingStore::format();
}
void QCocoaBackingStore::flush(QWindow *win, const QRegion &region, const QPoint &offset)
void QCocoaBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
if (!m_qImage.isNull()) {
if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(win->handle()))
[cocoaWindow->m_qtView flushBackingStore:this region:region offset:offset];
}
}
if (m_image.isNull())
return;
QImage QCocoaBackingStore::toImage() const
{
return m_qImage;
}
void QCocoaBackingStore::resize(const QSize &size, const QRegion &)
{
m_requestedSize = size;
}
bool QCocoaBackingStore::scroll(const QRegion &area, int dx, int dy)
{
extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
const qreal devicePixelRatio = m_qImage.devicePixelRatio();
QPoint qpoint(dx * devicePixelRatio, dy * devicePixelRatio);
for (const QRect &rect : area) {
const QRect qrect(rect.topLeft() * devicePixelRatio, rect.size() * devicePixelRatio);
qt_scrollRectInImage(m_qImage, qrect, qpoint);
}
return true;
}
void QCocoaBackingStore::beginPaint(const QRegion &region)
{
if (m_qImage.hasAlphaChannel()) {
QPainter p(&m_qImage);
p.setCompositionMode(QPainter::CompositionMode_Source);
const QColor blank = Qt::transparent;
for (const QRect &rect : region)
p.fillRect(rect, blank);
}
}
qreal QCocoaBackingStore::getBackingStoreDevicePixelRatio()
{
return m_qImage.devicePixelRatio();
if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle()))
[cocoaWindow->m_qtView flushBackingStore:this region:region offset:offset];
}
QT_END_NAMESPACE

View File

@ -40,6 +40,7 @@
#include "qcocoacursor.h"
#include "qcocoawindow.h"
#include "qcocoahelpers.h"
#include <QtGui/private/qcoregraphics_p.h>
#include <QtGui/QBitmap>

View File

@ -43,6 +43,7 @@
#ifndef QT_NO_WIDGETS
#include <QtWidgets/qwidget.h>
#endif
#include <QtGui/private/qcoregraphics_p.h>
QT_BEGIN_NAMESPACE

View File

@ -69,25 +69,6 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list);
inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qstrlist)
{ return reinterpret_cast<NSMutableArray *>(qt_mac_QStringListToNSMutableArrayVoid(qstrlist)); }
NSImage *qt_mac_cgimage_to_nsimage(CGImageRef iamge);
NSImage *qt_mac_create_nsimage(const QPixmap &pm);
NSImage *qt_mac_create_nsimage(const QIcon &icon);
CGImageRef qt_mac_toCGImage(const QImage &qImage);
CGImageRef qt_mac_toCGImageMask(const QImage &qImage);
QImage qt_mac_toQImage(CGImageRef image);
QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size);
QColor qt_mac_toQColor(const NSColor *color);
QColor qt_mac_toQColor(CGColorRef color);
QBrush qt_mac_toQBrush(CGColorRef color);
QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup = QPalette::Normal);
// Creates a mutable shape, it's the caller's responsibility to release.
HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion &region);
OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage);
NSDragOperation qt_mac_mapDropAction(Qt::DropAction action);
NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions);
Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions);
@ -95,9 +76,6 @@ Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions);
// Misc
void qt_mac_transformProccessToForegroundApplication();
CGColorSpaceRef qt_mac_genericColorSpace();
CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget);
CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice);
QString qt_mac_applicationName();
int qt_mac_flipYCoordinate(int y);
@ -143,8 +121,6 @@ public:
}
};
CGContextRef qt_mac_cg_context(QPaintDevice *pdev);
template<typename T>
T qt_mac_resolveOption(const T &fallback, const QByteArray &environment)
{

View File

@ -47,6 +47,7 @@
#include <qpa/qplatformscreen.h>
#include <private/qguiapplication_p.h>
#include <private/qwindow_p.h>
#include <QtGui/private/qcoregraphics_p.h>
#ifndef QT_NO_WIDGETS
#include <QtWidgets/QWidget>
@ -56,25 +57,6 @@
#include <Carbon/Carbon.h>
@interface NSGraphicsContext (QtAdditions)
+ (NSGraphicsContext *)qt_graphicsContextWithCGContext:(CGContextRef)graphicsPort flipped:(BOOL)initialFlippedState;
@end
@implementation NSGraphicsContext (QtAdditions)
+ (NSGraphicsContext *)qt_graphicsContextWithCGContext:(CGContextRef)graphicsPort flipped:(BOOL)initialFlippedState
{
#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_10, __IPHONE_NA)
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::OSXYosemite)
return [self graphicsContextWithCGContext:graphicsPort flipped:initialFlippedState];
#endif
return [self graphicsContextWithGraphicsPort:graphicsPort flipped:initialFlippedState];
}
@end
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaCocoaWindow, "qt.qpa.cocoa.window");
@ -101,198 +83,6 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list)
return result;
}
CGImageRef qt_mac_toCGImage(const QImage &inImage)
{
CGImageRef cgImage = inImage.toCGImage();
if (cgImage)
return cgImage;
// Convert image data to a known-good format if the fast conversion fails.
return inImage.convertToFormat(QImage::Format_ARGB32_Premultiplied).toCGImage();
}
CGImageRef qt_mac_toCGImageMask(const QImage &image)
{
static const auto deleter = [](void *image, const void *, size_t) { delete static_cast<QImage *>(image); };
QCFType<CGDataProviderRef> dataProvider =
CGDataProviderCreateWithData(new QImage(image), image.bits(),
image.byteCount(), deleter);
return CGImageMaskCreate(image.width(), image.height(), 8, image.depth(),
image.bytesPerLine(), dataProvider, NULL, false);
}
NSImage *qt_mac_cgimage_to_nsimage(CGImageRef image)
{
NSImage *newImage = [[NSImage alloc] initWithCGImage:image size:NSZeroSize];
return newImage;
}
NSImage *qt_mac_create_nsimage(const QPixmap &pm)
{
if (pm.isNull())
return 0;
QImage image = pm.toImage();
CGImageRef cgImage = qt_mac_toCGImage(image);
NSImage *nsImage = qt_mac_cgimage_to_nsimage(cgImage);
CGImageRelease(cgImage);
return nsImage;
}
NSImage *qt_mac_create_nsimage(const QIcon &icon)
{
if (icon.isNull())
return nil;
NSImage *nsImage = [[NSImage alloc] init];
foreach (QSize size, icon.availableSizes()) {
QPixmap pm = icon.pixmap(size);
QImage image = pm.toImage();
CGImageRef cgImage = qt_mac_toCGImage(image);
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
[nsImage addRepresentation:imageRep];
[imageRep release];
CGImageRelease(cgImage);
}
return nsImage;
}
HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion &region)
{
HIMutableShapeRef shape = HIShapeCreateMutable();
for (const QRect &rect : region) {
CGRect cgRect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
HIShapeUnionWithRect(shape, &cgRect);
}
return shape;
}
QColor qt_mac_toQColor(const NSColor *color)
{
QColor qtColor;
NSString *colorSpace = [color colorSpaceName];
if (colorSpace == NSDeviceCMYKColorSpace) {
CGFloat cyan, magenta, yellow, black, alpha;
[color getCyan:&cyan magenta:&magenta yellow:&yellow black:&black alpha:&alpha];
qtColor.setCmykF(cyan, magenta, yellow, black, alpha);
} else {
NSColor *tmpColor;
tmpColor = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace];
CGFloat red, green, blue, alpha;
[tmpColor getRed:&red green:&green blue:&blue alpha:&alpha];
qtColor.setRgbF(red, green, blue, alpha);
}
return qtColor;
}
QColor qt_mac_toQColor(CGColorRef color)
{
QColor qtColor;
CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(color));
const CGFloat *components = CGColorGetComponents(color);
if (model == kCGColorSpaceModelRGB) {
qtColor.setRgbF(components[0], components[1], components[2], components[3]);
} else if (model == kCGColorSpaceModelCMYK) {
qtColor.setCmykF(components[0], components[1], components[2], components[3]);
} else if (model == kCGColorSpaceModelMonochrome) {
qtColor.setRgbF(components[0], components[0], components[0], components[1]);
} else {
// Colorspace we can't deal with.
qWarning("Qt: qt_mac_toQColor: cannot convert from colorspace model: %d", model);
Q_ASSERT(false);
}
return qtColor;
}
QBrush qt_mac_toQBrush(CGColorRef color)
{
QBrush qtBrush;
CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(color));
if (model == kCGColorSpaceModelPattern) {
// Colorspace we can't deal with; the color is drawn directly using a callback.
qWarning("Qt: qt_mac_toQBrush: cannot convert from colorspace model: %d", model);
Q_ASSERT(false);
} else {
qtBrush.setStyle(Qt::SolidPattern);
qtBrush.setColor(qt_mac_toQColor(color));
}
return qtBrush;
}
static bool qt_mac_isSystemColorOrInstance(const NSColor *color, NSString *colorNameComponent, NSString *className)
{
// We specifically do not want isKindOfClass: here
if ([color.className isEqualToString:className]) // NSPatternColorSpace
return true;
if ([color.catalogNameComponent isEqualToString:@"System"] &&
[color.colorNameComponent isEqualToString:colorNameComponent] &&
[color.colorSpaceName isEqualToString:NSNamedColorSpace])
return true;
return false;
}
QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup)
{
QBrush qtBrush;
// QTBUG-49773: This calls NSDrawMenuItemBackground to render a 1 by n gradient; could use HITheme
if ([color.className isEqualToString:@"NSMenuItemHighlightColor"]) {
qWarning("Qt: qt_mac_toQBrush: cannot convert from NSMenuItemHighlightColor");
return qtBrush;
}
// Not a catalog color or a manifestation of System.windowBackgroundColor;
// only retrieved from NSWindow.backgroundColor directly
if ([color.className isEqualToString:@"NSMetalPatternColor"]) {
// NSTexturedBackgroundWindowMask, could theoretically handle this without private API by
// creating a window with the appropriate properties and then calling NSWindow.backgroundColor.patternImage,
// which returns a texture sized 1 by (window height, including frame), backed by a CGPattern
// which follows the window key state... probably need to allow QBrush to store a function pointer
// like CGPattern does
qWarning("Qt: qt_mac_toQBrush: cannot convert from NSMetalPatternColor");
return qtBrush;
}
// No public API to get these colors/stops;
// both accurately obtained through runtime object inspection on OS X 10.11
// (the NSColor object has NSGradient i-vars for both color groups)
if (qt_mac_isSystemColorOrInstance(color, @"_sourceListBackgroundColor", @"NSSourceListBackgroundColor")) {
QLinearGradient gradient;
if (colorGroup == QPalette::Active) {
gradient.setColorAt(0, QColor(233, 237, 242));
gradient.setColorAt(0.5, QColor(225, 229, 235));
gradient.setColorAt(1, QColor(209, 216, 224));
} else {
gradient.setColorAt(0, QColor(248, 248, 248));
gradient.setColorAt(0.5, QColor(240, 240, 240));
gradient.setColorAt(1, QColor(235, 235, 235));
}
return QBrush(gradient);
}
// A couple colors are special... they are actually instances of NSGradientPatternColor, which
// override set/setFill/setStroke to instead initialize an internal color
// ([NSColor colorWithCalibratedWhite:0.909804 alpha:1.000000]) while still returning the
// ruled lines pattern image (from OS X 10.4) to the user from -[NSColor patternImage]
// (and providing no public API to get the underlying color without this insanity)
if (qt_mac_isSystemColorOrInstance(color, @"controlColor", @"NSGradientPatternColor") ||
qt_mac_isSystemColorOrInstance(color, @"windowBackgroundColor", @"NSGradientPatternColor")) {
qtBrush.setStyle(Qt::SolidPattern);
qtBrush.setColor(qt_mac_toQColor(color.CGColor));
return qtBrush;
}
if (NSColor *patternColor = [color colorUsingColorSpaceName:NSPatternColorSpace]) {
NSImage *patternImage = patternColor.patternImage;
const QSizeF sz(patternImage.size.width, patternImage.size.height);
qtBrush.setTexture(qt_mac_toQPixmap(patternImage, sz)); // QTBUG-49774
} else {
qtBrush.setStyle(Qt::SolidPattern);
qtBrush.setColor(qt_mac_toQColor(color));
}
return qtBrush;
}
struct dndenum_mapper
{
NSDragOperation mac_code;
@ -402,97 +192,6 @@ void qt_mac_transformProccessToForegroundApplication()
[[NSApplication sharedApplication] setActivationPolicy:NSApplicationActivationPolicyRegular];
}
}
static CGColorSpaceRef m_genericColorSpace = 0;
static QHash<CGDirectDisplayID, CGColorSpaceRef> m_displayColorSpaceHash;
static bool m_postRoutineRegistered = false;
CGColorSpaceRef qt_mac_genericColorSpace()
{
#if 0
if (!m_genericColorSpace) {
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
} else
{
m_genericColorSpace = CGColorSpaceCreateDeviceRGB();
}
if (!m_postRoutineRegistered) {
m_postRoutineRegistered = true;
qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces);
}
}
return m_genericColorSpace;
#else
// Just return the main display colorspace for the moment.
return qt_mac_displayColorSpace(0);
#endif
}
/*
Ideally, we should pass the widget in here, and use CGGetDisplaysWithRect() etc.
to support multiple displays correctly.
*/
CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget)
{
CGColorSpaceRef colorSpace;
CGDirectDisplayID displayID;
if (widget == 0) {
displayID = CGMainDisplayID();
} else {
displayID = CGMainDisplayID();
/*
### get correct display
const QRect &qrect = widget->window()->geometry();
CGRect rect = CGRectMake(qrect.x(), qrect.y(), qrect.width(), qrect.height());
CGDisplayCount throwAway;
CGDisplayErr dErr = CGGetDisplaysWithRect(rect, 1, &displayID, &throwAway);
if (dErr != kCGErrorSuccess)
return macDisplayColorSpace(0); // fall back on main display
*/
}
if ((colorSpace = m_displayColorSpaceHash.value(displayID)))
return colorSpace;
colorSpace = CGDisplayCopyColorSpace(displayID);
if (colorSpace == 0)
colorSpace = CGColorSpaceCreateDeviceRGB();
m_displayColorSpaceHash.insert(displayID, colorSpace);
if (!m_postRoutineRegistered) {
m_postRoutineRegistered = true;
void qt_mac_cleanUpMacColorSpaces();
qAddPostRoutine(qt_mac_cleanUpMacColorSpaces);
}
return colorSpace;
}
void qt_mac_cleanUpMacColorSpaces()
{
if (m_genericColorSpace) {
CFRelease(m_genericColorSpace);
m_genericColorSpace = 0;
}
QHash<CGDirectDisplayID, CGColorSpaceRef>::const_iterator it = m_displayColorSpaceHash.constBegin();
while (it != m_displayColorSpaceHash.constEnd()) {
if (it.value())
CFRelease(it.value());
++it;
}
m_displayColorSpaceHash.clear();
}
CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice)
{
#ifdef QT_NO_WIDGETS
Q_UNUSED(paintDevice)
return qt_mac_displayColorSpace(0);
#else
bool isWidget = (paintDevice->devType() == QInternal::Widget);
return qt_mac_displayColorSpace(isWidget ? static_cast<const QWidget *>(paintDevice): 0);
#endif
}
QString qt_mac_applicationName()
{
@ -557,28 +256,6 @@ NSRect qt_mac_flipRect(const QRect &rect)
return NSMakeRect(rect.x(), flippedY, rect.width(), rect.height());
}
OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage)
{
// Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev)
OSStatus err = noErr;
require_action(inContext != NULL, InvalidContext, err = paramErr);
require_action(inBounds != NULL, InvalidBounds, err = paramErr);
require_action(inImage != NULL, InvalidImage, err = paramErr);
CGContextSaveGState( inContext );
CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds));
CGContextScaleCTM(inContext, 1, -1);
CGContextDrawImage(inContext, *inBounds, inImage);
CGContextRestoreGState(inContext);
InvalidImage:
InvalidBounds:
InvalidContext:
return err;
}
Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum)
{
if (buttonNum == 0)
@ -599,81 +276,4 @@ QString qt_mac_removeAmpersandEscapes(QString s)
return QPlatformTheme::removeMnemonics(s).trimmed();
}
/*! \internal
Returns the CoreGraphics CGContextRef of the paint device. 0 is
returned if it can't be obtained. It is the caller's responsibility to
CGContextRelease the context when finished using it.
\warning This function is only available on \macos.
\warning This function is duplicated in qmacstyle_mac.mm
*/
CGContextRef qt_mac_cg_context(QPaintDevice *pdev)
{
// In Qt 5, QWidget and QPixmap (and QImage) paint devices are all QImages under the hood.
QImage *image = 0;
if (pdev->devType() == QInternal::Image) {
image = static_cast<QImage *>(pdev);
} else if (pdev->devType() == QInternal::Pixmap) {
const QPixmap *pm = static_cast<const QPixmap*>(pdev);
QPlatformPixmap *data = const_cast<QPixmap *>(pm)->data_ptr().data();
if (data && data->classId() == QPlatformPixmap::RasterClass) {
image = data->buffer();
} else {
qDebug("qt_mac_cg_context: Unsupported pixmap class");
}
} else if (pdev->devType() == QInternal::Widget) {
// TODO test: image = static_cast<QImage *>(static_cast<const QWidget *>(pdev)->backingStore()->paintDevice());
qDebug("qt_mac_cg_context: not implemented: Widget class");
}
if (!image)
return 0; // Context type not supported.
CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev);
uint flags = kCGImageAlphaPremultipliedFirst;
flags |= kCGBitmapByteOrder32Host;
CGContextRef ret = 0;
ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(),
8, image->bytesPerLine(), colorspace, flags);
CGContextTranslateCTM(ret, 0, image->height());
CGContextScaleCTM(ret, 1, -1);
return ret;
}
QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size)
{
const NSSize pixmapSize = NSMakeSize(size.width(), size.height());
QPixmap pixmap(pixmapSize.width, pixmapSize.height);
pixmap.fill(Qt::transparent);
[image setSize:pixmapSize];
const NSRect iconRect = NSMakeRect(0, 0, pixmapSize.width, pixmapSize.height);
QMacCGContext ctx(&pixmap);
if (!ctx)
return QPixmap();
NSGraphicsContext *gc = [NSGraphicsContext qt_graphicsContextWithCGContext:ctx flipped:YES];
if (!gc)
return QPixmap();
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:gc];
[image drawInRect:iconRect fromRect:iconRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil];
[NSGraphicsContext restoreGraphicsState];
return pixmap;
}
QImage qt_mac_toQImage(CGImageRef image)
{
const size_t w = CGImageGetWidth(image),
h = CGImageGetHeight(image);
QImage ret(w, h, QImage::Format_ARGB32_Premultiplied);
ret.fill(Qt::transparent);
CGRect rect = CGRectMake(0, 0, w, h);
CGContextRef ctx = qt_mac_cg_context(&ret);
qt_mac_drawCGImage(ctx, &rect, image);
CGContextRelease(ctx);
return ret;
}
QT_END_NAMESPACE

View File

@ -58,6 +58,8 @@
#include <qpa/qplatforminputcontextfactory_p.h>
#include <QtCore/qcoreapplication.h>
#include <QtGui/private/qcoregraphics_p.h>
#include <IOKit/graphics/IOGraphicsLib.h>
static void initResources()
@ -199,8 +201,6 @@ QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const
return window;
}
extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev);
QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height) const
{
// TODO window should be handled
@ -251,9 +251,8 @@ QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height
QPixmap pix(w, h);
pix.fill(Qt::transparent);
CGRect rect = CGRectMake(0, 0, w, h);
CGContextRef ctx = qt_mac_cg_context(&pix);
QMacCGContext ctx(&pix);
qt_mac_drawCGImage(ctx, &rect, image);
CGContextRelease(ctx);
QPainter painter(&windowPixmap);
painter.drawPixmap(0, 0, pix);

View File

@ -48,6 +48,7 @@
#include "qt_mac_p.h"
#include "qcocoaapplication.h" // for custom application category
#include "qcocoamenuloader.h"
#include <QtGui/private/qcoregraphics_p.h>
#include <QtCore/QDebug>

View File

@ -40,6 +40,7 @@
#include "qcocoamimetypes.h"
#include <QtPlatformSupport/private/qmacmime_p.h>
#include "qcocoahelpers.h"
#include <QtGui/private/qcoregraphics_p.h>
QT_BEGIN_NAMESPACE

View File

@ -64,6 +64,8 @@
#include <qpa/qplatformprintersupport.h>
#endif
#include <QtGui/private/qcoregraphics_p.h>
#include <QtPlatformHeaders/qcocoawindowfunctions.h>
#include <AppKit/AppKit.h>

View File

@ -43,6 +43,7 @@
#include <QtCore/private/qcore_mac_p.h>
#include <QtGui/qfont.h>
#include <QtGui/private/qcoregraphics_p.h>
#include <Carbon/Carbon.h>

View File

@ -86,6 +86,7 @@
#include "qt_mac_p.h"
#include "qcocoahelpers.h"
#include <QtGui/private/qcoregraphics_p.h>
#import <AppKit/AppKit.h>

View File

@ -56,6 +56,7 @@
#include <QtCore/qfileinfo.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qcoregraphics_p.h>
#include <QtGui/qpainter.h>
#include <QtPlatformSupport/private/qcoretextfontdatabase_p.h>
#include <QtPlatformSupport/private/qabstractfileiconengine_p.h>
@ -197,7 +198,7 @@ QPixmap qt_mac_convert_iconref(const IconRef icon, int width, int height)
CGRect rect = CGRectMake(0, 0, width, height);
CGContextRef ctx = qt_mac_cg_context(&ret);
QMacCGContext ctx(&ret);
CGAffineTransform old_xform = CGContextGetCTM(ctx);
CGContextConcatCTM(ctx, CGAffineTransformInvert(old_xform));
CGContextConcatCTM(ctx, CGAffineTransformIdentity);
@ -205,7 +206,6 @@ QPixmap qt_mac_convert_iconref(const IconRef icon, int width, int height)
::RGBColor b;
b.blue = b.green = b.red = 255*255;
PlotIconRefInContext(ctx, &rect, kAlignNone, kTransformNone, &b, kPlotIconRefNormalFlags, icon);
CGContextRelease(ctx);
return ret;
}

View File

@ -52,6 +52,7 @@
#include <private/qwindow_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformscreen.h>
#include <QtGui/private/qcoregraphics_p.h>
#include <AppKit/AppKit.h>

View File

@ -52,6 +52,7 @@
#include <QtCore/QDebug>
#include <QtCore/qsysinfo.h>
#include <private/qguiapplication_p.h>
#include <private/qcoregraphics_p.h>
#include "qcocoabackingstore.h"
#ifndef QT_NO_OPENGL
#include "qcocoaglcontext.h"
@ -494,7 +495,7 @@ static bool _q_dontOverrideCtrlLMB = false;
qCDebug(lcQpaCocoaWindow) << "[QNSView flushBackingStore:]" << m_window << region.rectCount() << region.boundingRect() << offset;
m_backingStore = backingStore;
m_backingStoreOffset = offset * m_backingStore->getBackingStoreDevicePixelRatio();
m_backingStoreOffset = offset * m_backingStore->paintDevice()->devicePixelRatio();
for (const QRect &rect : region)
[self setNeedsDisplayInRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())];
}
@ -576,7 +577,7 @@ static bool _q_dontOverrideCtrlLMB = false;
// The backing store source rect will be larger on retina displays.
// Scale dirtyRect by the device pixel ratio:
const qreal devicePixelRatio = m_backingStore->getBackingStoreDevicePixelRatio();
const qreal devicePixelRatio = m_backingStore->paintDevice()->devicePixelRatio();
CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * devicePixelRatio,
dirtyRect.origin.y * devicePixelRatio,
dirtyRect.size.width * devicePixelRatio,

View File

@ -63,6 +63,7 @@
#include <private/qpainter_p.h>
#include <private/qpainterpath_p.h>
#include <private/qtextengine_p.h>
#include <private/qcoregraphics_p.h>
#include "qcocoahelpers.h"
@ -74,84 +75,6 @@ QT_BEGIN_NAMESPACE
QCoreGraphicsPaintEngine utility functions
*****************************************************************************/
static void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform)
{
CGAffineTransform old_xform = CGAffineTransformIdentity;
if (orig_xform) { //setup xforms
old_xform = CGContextGetCTM(hd);
CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform));
CGContextConcatCTM(hd, *orig_xform);
}
//do the clipping
CGContextBeginPath(hd);
if (rgn.isEmpty()) {
CGContextAddRect(hd, CGRectMake(0, 0, 0, 0));
} else {
for (const QRect &r : rgn) {
CGRect mac_r = CGRectMake(r.x(), r.y(), r.width(), r.height());
CGContextAddRect(hd, mac_r);
}
}
CGContextClip(hd);
if (orig_xform) {//reset xforms
CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd)));
CGContextConcatCTM(hd, old_xform);
}
}
// Implemented for qt_mac_p.h
QMacCGContext::QMacCGContext(QPainter *p)
{
QPaintEngine *pe = p->paintEngine();
#ifndef QT_NO_PRINTER
if (pe->type() == QPaintEngine::MacPrinter)
pe = static_cast<QMacPrintEngine*>(pe)->paintEngine();
#endif
pe->syncState();
context = 0;
if (pe->type() == QPaintEngine::CoreGraphics)
context = static_cast<QCoreGraphicsPaintEngine*>(pe)->handle();
int devType = p->device()->devType();
if (pe->type() == QPaintEngine::Raster
&& (devType == QInternal::Widget || devType == QInternal::Pixmap || devType == QInternal::Image)) {
CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pe->paintDevice());
uint flags = kCGImageAlphaPremultipliedFirst;
#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
flags |= kCGBitmapByteOrder32Host;
#endif
const QImage *image = (const QImage *) pe->paintDevice();
context = CGBitmapContextCreate((void *) image->bits(), image->width(), image->height(),
8, image->bytesPerLine(), colorspace, flags);
CGContextTranslateCTM(context, 0, image->height());
CGContextScaleCTM(context, 1, -1);
if (devType == QInternal::Widget) {
QRegion clip = p->paintEngine()->systemClip();
QTransform native = p->deviceTransform();
if (p->hasClipping()) {
QRegion r = p->clipRegion();
r.translate(native.dx(), native.dy());
if (clip.isEmpty())
clip = r;
else
clip &= r;
}
qt_mac_clip_cg(context, clip, 0);
CGContextTranslateCTM(context, native.dx(), native.dy());
}
} else {
CGContextRetain(context);
}
}
void qt_mac_cgimage_data_free(void *, const void *memoryToFree, size_t)
{
free(const_cast<void *>(memoryToFree));
@ -453,7 +376,7 @@ static void qt_mac_draw_pattern(void *info, CGContextRef c)
const QColor c0(0, 0, 0, 0), c1(255, 255, 255, 255);
QPixmap pm(w*QMACPATTERN_MASK_MULTIPLIER, h*QMACPATTERN_MASK_MULTIPLIER);
pm.fill(c0);
CGContextRef pm_ctx = qt_mac_cg_context(&pm);
QMacCGContext pm_ctx(&pm);
CGContextSetFillColorWithColor(c, cgColorForQColor(c1, pat->pdev));
CGRect rect = CGRectMake(0, 0, w, h);
for (int x = 0; x < QMACPATTERN_MASK_MULTIPLIER; ++x) {
@ -543,7 +466,8 @@ QCoreGraphicsPaintEngine::begin(QPaintDevice *pdev)
d->cosmeticPenSize = 1;
d->current.clipEnabled = false;
d->pixelSize = QPoint(1,1);
d->hd = qt_mac_cg_context(pdev);
QMacCGContext ctx(pdev);
d->hd = CGContextRetain(ctx);
if (d->hd) {
d->saveGraphicsState();
d->orig_xform = CGContextGetCTM(d->hd);

View File

@ -149,6 +149,9 @@ public:
PMPageFormat format() const { return static_cast<PMPageFormat>([printInfo PMPageFormat]); }
PMPrintSession session() const { return static_cast<PMPrintSession>([printInfo PMPrintSession]); }
PMPrintSettings settings() const { return static_cast<PMPrintSettings>([printInfo PMPrintSettings]); }
QPaintEngine *aggregateEngine() Q_DECL_OVERRIDE { return paintEngine; }
Qt::HANDLE nativeHandle() Q_DECL_OVERRIDE { return q_func()->handle(); }
};
QT_END_NAMESPACE

View File

@ -90,44 +90,6 @@ public:
}
};
class QMacCGContext
{
CGContextRef context;
public:
QMacCGContext(QPainter *p); //qpaintengine_mac.mm
inline QMacCGContext() { context = 0; }
inline QMacCGContext(QPaintDevice *pdev) {
extern CGContextRef qt_mac_cg_context(QPaintDevice *);
context = qt_mac_cg_context(pdev);
}
inline QMacCGContext(CGContextRef cg, bool takeOwnership=false) {
context = cg;
if(!takeOwnership)
CGContextRetain(context);
}
inline QMacCGContext(const QMacCGContext &copy) : context(0) { *this = copy; }
inline ~QMacCGContext() {
if(context)
CGContextRelease(context);
}
inline bool isNull() const { return context; }
inline operator CGContextRef() { return context; }
inline QMacCGContext &operator=(const QMacCGContext &copy) {
if(context)
CGContextRelease(context);
context = copy.context;
CGContextRetain(context);
return *this;
}
inline QMacCGContext &operator=(CGContextRef cg) {
if(context)
CGContextRelease(context);
context = cg;
CGContextRetain(context); //we do not take ownership
return *this;
}
};
class QMacInternalPasteboardMime;
class QMimeData;

View File

@ -91,7 +91,7 @@ QMimeData *QHaikuClipboard::mimeData(QClipboard::Mode mode)
const status_t status = clipboard->FindData(name, B_MIME_TYPE, &data, &dataLen);
if (dataLen && (status == B_OK)) {
const QString format = QString::fromLatin1(name);
const QLatin1String format(name);
if (format == QLatin1String("text/plain")) {
m_systemMimeData->setText(QString::fromLocal8Bit(reinterpret_cast<const char*>(data), dataLen));
} else if (format == QLatin1String("text/html")) {

View File

@ -49,6 +49,8 @@
#include <QtDebug>
QT_BEGIN_NAMESPACE
class QIOSPaintDevice : public QOpenGLPaintDevice
{
public:

View File

@ -48,6 +48,8 @@
#import <OpenGLES/ES2/glext.h>
#import <QuartzCore/CAEAGLLayer.h>
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaGLContext, "qt.qpa.glcontext");
QIOSContext::QIOSContext(QOpenGLContext *context)
@ -314,3 +316,4 @@ bool QIOSContext::isSharing() const
#include "moc_qioscontext.cpp"
QT_END_NAMESPACE

View File

@ -43,10 +43,10 @@
#include <QtCore/qeventloop.h>
#include <qpa/qplatformdialoghelper.h>
QT_BEGIN_NAMESPACE
Q_FORWARD_DECLARE_OBJC_CLASS(UIViewController);
QT_BEGIN_NAMESPACE
class QIOSFileDialog : public QPlatformFileDialogHelper
{
public:

View File

@ -74,6 +74,8 @@ QT_END_NAMESPACE
+ (id)currentFirstResponder;
@end
QT_BEGIN_NAMESPACE
class FirstResponderCandidate : public QScopedValueRollback<UIResponder *>
{
public:
@ -84,4 +86,6 @@ private:
static UIResponder *s_firstResponderCandidate;
};
QT_END_NAMESPACE
#endif // QIOSGLOBAL_H

View File

@ -114,6 +114,8 @@ int infoPlistValue(NSString* key, int defaultValue)
return value ? [value intValue] : defaultValue;
}
QT_END_NAMESPACE
// -------------------------------------------------------------------------
@interface QtFirstResponderEvent : UIEvent
@ -164,6 +166,8 @@ int infoPlistValue(NSString* key, int defaultValue)
}
@end
QT_BEGIN_NAMESPACE
FirstResponderCandidate::FirstResponderCandidate(UIResponder *responder)
: QScopedValueRollback<UIResponder *>(s_firstResponderCandidate, responder)
{

View File

@ -51,13 +51,13 @@ const char kImePlatformDataInputView[] = "inputView";
const char kImePlatformDataInputAccessoryView[] = "inputAccessoryView";
const char kImePlatformDataReturnKeyType[] = "returnKeyType";
QT_BEGIN_NAMESPACE
@class QIOSLocaleListener;
@class QIOSKeyboardListener;
@class QIOSTextInputResponder;
@protocol KeyboardState;
QT_BEGIN_NAMESPACE
struct KeyboardState
{
KeyboardState() :

View File

@ -97,14 +97,14 @@ static QUIView *focusView()
@interface QIOSKeyboardListener : UIGestureRecognizer <UIGestureRecognizerDelegate> {
@private
QIOSInputContext *m_context;
QT_PREPEND_NAMESPACE(QIOSInputContext) *m_context;
}
@property BOOL hasDeferredScrollToCursor;
@end
@implementation QIOSKeyboardListener
- (id)initWithQIOSInputContext:(QIOSInputContext *)context
- (id)initWithQIOSInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)context
{
if (self = [super initWithTarget:self action:@selector(gestureStateChanged:)]) {
@ -291,6 +291,8 @@ static QUIView *focusView()
// -------------------------------------------------------------------------
QT_BEGIN_NAMESPACE
Qt::InputMethodQueries ImeState::update(Qt::InputMethodQueries properties)
{
if (!properties)
@ -713,3 +715,5 @@ QLocale QIOSInputContext::locale() const
{
return QLocale(QString::fromNSString([[NSLocale currentLocale] objectForKey:NSLocaleIdentifier]));
}
QT_END_NAMESPACE

View File

@ -43,11 +43,11 @@
#include <QtCore/qeventloop.h>
#include <qpa/qplatformdialoghelper.h>
QT_BEGIN_NAMESPACE
Q_FORWARD_DECLARE_OBJC_CLASS(UIAlertController);
Q_FORWARD_DECLARE_OBJC_CLASS(UIAlertAction);
QT_BEGIN_NAMESPACE
class QIOSMessageDialog : public QPlatformMessageDialogHelper
{
public:

View File

@ -65,7 +65,7 @@ void invalidateCache(QAccessibleInterface *iface)
// when items get added or removed from the screen
foreach (QWindow *win, QGuiApplication::topLevelWindows()) {
if (win && win->handle()) {
QIOSWindow *window = static_cast<QIOSWindow*>(win->handle());
QT_PREPEND_NAMESPACE(QIOSWindow) *window = static_cast<QT_PREPEND_NAMESPACE(QIOSWindow) *>(win->handle());
window->clearAccessibleCache();
}
}

View File

@ -68,6 +68,8 @@ public:
Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE;
void setOrientationUpdateMask(Qt::ScreenOrientations mask) Q_DECL_OVERRIDE;
QPixmap grabWindow(WId window, int x, int y, int width, int height) const override;
UIScreen *uiScreen() const;
UIWindow *uiWindow() const;

View File

@ -48,6 +48,7 @@
#include <QtCore/qoperatingsystemversion.h>
#include <QtGui/private/qwindow_p.h>
#include <private/qcoregraphics_p.h>
#include <sys/sysctl.h>
@ -176,6 +177,8 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
// -------------------------------------------------------------------------
QT_BEGIN_NAMESPACE
/*!
Returns the model identifier of the device.
@ -458,6 +461,38 @@ void QIOSScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask)
}
}
QPixmap QIOSScreen::grabWindow(WId window, int x, int y, int width, int height) const
{
if (window && ![reinterpret_cast<id>(window) isKindOfClass:[UIView class]])
return QPixmap();
UIView *view = window ? reinterpret_cast<UIView *>(window) : m_uiWindow;
if (width < 0)
width = qMax(view.bounds.size.width - x, CGFloat(0));
if (height < 0)
height = qMax(view.bounds.size.height - y, CGFloat(0));
CGRect captureRect = [m_uiWindow convertRect:CGRectMake(x, y, width, height) fromView:view];
captureRect = CGRectIntersection(captureRect, m_uiWindow.bounds);
UIGraphicsBeginImageContextWithOptions(captureRect.size, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, -captureRect.origin.x, -captureRect.origin.y);
// Draws the complete view hierarchy of m_uiWindow into the given rect, which
// needs to be the same aspect ratio as the m_uiWindow's size. Since we've
// translated the graphics context, and are potentially drawing into a smaller
// context than the full window, the resulting image will be a subsection of the
// full screen.
[m_uiWindow drawViewHierarchyInRect:m_uiWindow.bounds afterScreenUpdates:NO];
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return QPixmap::fromImage(qt_mac_toQImage(screenshot.CGImage));
}
UIScreen *QIOSScreen::uiScreen() const
{
return m_uiScreen;

View File

@ -42,19 +42,23 @@
#include <QtCore/qstring.h>
#include <QtGui/qevent.h>
QT_BEGIN_NAMESPACE
class QIOSInputContext;
QT_END_NAMESPACE
@interface QIOSTextInputResponder : UIResponder <UITextInputTraits, UIKeyInput, UITextInput>
{
@private
QIOSInputContext *m_inputContext;
QInputMethodQueryEvent *m_configuredImeState;
QT_PREPEND_NAMESPACE(QIOSInputContext) *m_inputContext;
QT_PREPEND_NAMESPACE(QInputMethodQueryEvent) *m_configuredImeState;
QString m_markedText;
BOOL m_inSendEventToFocusObject;
BOOL m_inSelectionChange;
}
- (id)initWithInputContext:(QIOSInputContext *)context;
- (id)initWithInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)context;
- (BOOL)needsKeyboardReconfigure:(Qt::InputMethodQueries)updatedProperties;
- (void)notifyInputDelegate:(Qt::InputMethodQueries)updatedProperties;

View File

@ -163,7 +163,7 @@
@implementation QIOSTextInputResponder
- (id)initWithInputContext:(QIOSInputContext *)inputContext
- (id)initWithInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)inputContext
{
if (!(self = [self init]))
return self;

View File

@ -38,12 +38,17 @@
****************************************************************************/
#import <UIKit/UIKit.h>
#include <QtCore/QtGlobal>
QT_BEGIN_NAMESPACE
class QIOSScreen;
QT_END_NAMESPACE
@interface QIOSViewController : UIViewController
- (id)initWithQIOSScreen:(QIOSScreen *)screen;
- (id)initWithQIOSScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen;
- (void)updateProperties;
#ifndef Q_OS_TVOS

View File

@ -58,7 +58,7 @@
@interface QIOSViewController () {
@public
QPointer<QIOSScreen> m_screen;
QPointer<QT_PREPEND_NAMESPACE(QIOSScreen)> m_screen;
BOOL m_updatingProperties;
QMetaObject::Connection m_focusWindowChangeConnection;
}
@ -126,7 +126,7 @@
{
Q_UNUSED(subview);
QIOSScreen *screen = self.qtViewController->m_screen;
QT_PREPEND_NAMESPACE(QIOSScreen) *screen = self.qtViewController->m_screen;
// The 'window' property of our view is not valid until the window
// has been shown, so we have to access it through the QIOSScreen.
@ -229,7 +229,7 @@
@implementation QIOSViewController
- (id)initWithQIOSScreen:(QIOSScreen *)screen
- (id)initWithQIOSScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen
{
if (self = [self init]) {
m_screen = screen;

View File

@ -48,10 +48,10 @@
class QIOSContext;
class QIOSWindow;
QT_BEGIN_NAMESPACE
@class QUIView;
QT_BEGIN_NAMESPACE
class QIOSWindow : public QObject, public QPlatformWindow
{
Q_OBJECT

View File

@ -54,6 +54,8 @@
#include <QtDebug>
QT_BEGIN_NAMESPACE
QIOSWindow::QIOSWindow(QWindow *window)
: QPlatformWindow(window)
, m_view([[QUIView alloc] initWithQIOSWindow:this])

View File

@ -63,7 +63,7 @@
QAccessibleCache *cache = QAccessibleCache::instance();
QMacAccessibilityElement *element = cache->elementForId(anId);
QT_MANGLE_NAMESPACE(QMacAccessibilityElement) *element = cache->elementForId(anId);
if (!element) {
Q_ASSERT(QAccessible::accessibleInterface(anId));
element = [[self alloc] initWithId:anId withAccessibilityContainer: view];

View File

@ -44,14 +44,18 @@
#include <qpa/qwindowsysteminterface.h>
QT_BEGIN_NAMESPACE
class QIOSWindow;
QT_END_NAMESPACE
@class QIOSViewController;
@interface QUIView : UIView
{
@public
QIOSWindow *m_qioswindow;
QT_PREPEND_NAMESPACE(QIOSWindow) *m_qioswindow;
@private
QHash<UITouch *, QWindowSystemInterface::TouchPoint> m_activeTouches;
int m_nextTouchId;
@ -60,7 +64,7 @@ class QIOSWindow;
NSMutableArray *m_accessibleElements;
};
- (id)initWithQIOSWindow:(QIOSWindow *)window;
- (id)initWithQIOSWindow:(QT_PREPEND_NAMESPACE(QIOSWindow) *)window;
- (void)sendUpdatedExposeEvent;
- (BOOL)isActiveWindow;
@end

View File

@ -60,7 +60,7 @@
return [CAEAGLLayer class];
}
- (id)initWithQIOSWindow:(QIOSWindow *)window
- (id)initWithQIOSWindow:(QT_PREPEND_NAMESPACE(QIOSWindow) *)window
{
if (self = [self initWithFrame:window->geometry().toCGRect()])
m_qioswindow = window;
@ -525,7 +525,7 @@
- (QWindow *)qwindow
{
if ([self isKindOfClass:[QUIView class]]) {
if (QIOSWindow *w = static_cast<QUIView *>(self)->m_qioswindow)
if (QT_PREPEND_NAMESPACE(QIOSWindow) *w = static_cast<QUIView *>(self)->m_qioswindow)
return w->window();
}
return nil;

View File

@ -46,6 +46,7 @@
#include <QtCore/QSettings>
#include <QtCore/QtEndian>
#include <QtCore/QVarLengthArray>
#include <QtCore/QFile>
#include <private/qstringiterator_p.h>
#include <QtCore/private/qsystemlibrary_p.h>
@ -236,6 +237,82 @@ QWindowsFontEngineDirectWrite::~QWindowsFontEngineDirectWrite()
m_directWriteBitmapRenderTarget->Release();
}
#ifndef Q_CC_MINGW
typedef IDWriteLocalFontFileLoader QIdWriteLocalFontFileLoader;
static UUID uuidIdWriteLocalFontFileLoader()
{
return __uuidof(IDWriteLocalFontFileLoader);
}
#else // !Q_CC_MINGW
DECLARE_INTERFACE_(QIdWriteLocalFontFileLoader, IDWriteFontFileLoader)
{
STDMETHOD(GetFilePathLengthFromKey)(THIS_ void const *, UINT32, UINT32*) PURE;
STDMETHOD(GetFilePathFromKey)(THIS_ void const *, UINT32, WCHAR *, UINT32) PURE;
STDMETHOD(GetLastWriteTimeFromKey)(THIS_ void const *, UINT32, FILETIME *) PURE;
};
static UUID uuidIdWriteLocalFontFileLoader()
{
static const UUID result = { 0xb2d9f3ec, 0xc9fe, 0x4a11, {0xa2, 0xec, 0xd8, 0x62, 0x8, 0xf7, 0xc0, 0xa2}};
return result;
}
#endif // Q_CC_MINGW
QString QWindowsFontEngineDirectWrite::filenameFromFontFile(IDWriteFontFile *fontFile)
{
IDWriteFontFileLoader *loader = Q_NULLPTR;
HRESULT hr = fontFile->GetLoader(&loader);
if (FAILED(hr)) {
qErrnoWarning("%s: GetLoader failed", __FUNCTION__);
return QString();
}
QIdWriteLocalFontFileLoader *localLoader = Q_NULLPTR;
hr = loader->QueryInterface(uuidIdWriteLocalFontFileLoader(),
reinterpret_cast<void **>(&localLoader));
const void *fontFileReferenceKey = Q_NULLPTR;
UINT32 fontFileReferenceKeySize = 0;
if (SUCCEEDED(hr)) {
hr = fontFile->GetReferenceKey(&fontFileReferenceKey,
&fontFileReferenceKeySize);
if (FAILED(hr))
qErrnoWarning(hr, "%s: GetReferenceKey failed", __FUNCTION__);
}
UINT32 filePathLength = 0;
if (SUCCEEDED(hr)) {
hr = localLoader->GetFilePathLengthFromKey(fontFileReferenceKey,
fontFileReferenceKeySize,
&filePathLength);
if (FAILED(hr))
qErrnoWarning(hr, "GetFilePathLength failed", __FUNCTION__);
}
QString ret;
if (SUCCEEDED(hr) && filePathLength > 0) {
QVarLengthArray<wchar_t> filePath(filePathLength + 1);
hr = localLoader->GetFilePathFromKey(fontFileReferenceKey,
fontFileReferenceKeySize,
filePath.data(),
filePathLength + 1);
if (FAILED(hr))
qErrnoWarning(hr, "%s: GetFilePathFromKey failed", __FUNCTION__);
else
ret = QString::fromWCharArray(filePath.data());
}
if (localLoader != Q_NULLPTR)
localLoader->Release();
if (loader != Q_NULLPTR)
loader->Release();
return ret;
}
void QWindowsFontEngineDirectWrite::collectMetrics()
{
DWRITE_FONT_METRICS metrics;
@ -250,6 +327,13 @@ void QWindowsFontEngineDirectWrite::collectMetrics()
m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight);
m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap);
m_underlinePosition = DESIGN_TO_LOGICAL(metrics.underlinePosition);
IDWriteFontFile *fontFile = Q_NULLPTR;
UINT32 numberOfFiles = 1;
if (SUCCEEDED(m_directWriteFontFace->GetFiles(&numberOfFiles, &fontFile))) {
m_faceId.filename = QFile::encodeName(filenameFromFontFile(fontFile));
fontFile->Release();
}
}
QFixed QWindowsFontEngineDirectWrite::underlinePosition() const
@ -351,6 +435,11 @@ bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGly
return true;
}
QFontEngine::FaceId QWindowsFontEngineDirectWrite::faceId() const
{
return m_faceId;
}
void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const
{
QVarLengthArray<UINT16> glyphIndices(glyphs->numGlyphs);

View File

@ -49,6 +49,7 @@
struct IDWriteFont;
struct IDWriteFontFace;
struct IDWriteFontFile;
struct IDWriteFactory;
struct IDWriteBitmapRenderTarget;
struct IDWriteGdiInterop;
@ -92,6 +93,7 @@ public:
QFixed leading() const Q_DECL_OVERRIDE;
QFixed xHeight() const Q_DECL_OVERRIDE;
qreal maxCharWidth() const Q_DECL_OVERRIDE;
FaceId faceId() const Q_DECL_OVERRIDE;
bool supportsSubPixelPositions() const Q_DECL_OVERRIDE;
@ -113,6 +115,7 @@ private:
QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
void collectMetrics();
void renderGlyphRun(QImage *destination, float r, float g, float b, float a, IDWriteGlyphRunAnalysis *glyphAnalysis, const QRect &boundingRect);
static QString filenameFromFontFile(IDWriteFontFile *fontFile);
const QSharedPointer<QWindowsFontEngineData> m_fontEngineData;

View File

@ -86,30 +86,31 @@ QWinRTInputContext::QWinRTInputContext(QWinRTScreen *screen)
{
qCDebug(lcQpaInputMethods) << __FUNCTION__ << screen;
ComPtr<IInputPaneStatics> statics;
if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(),
&statics))) {
qWarning("failed to retrieve input pane statics.");
return;
}
QEventDispatcherWinRT::runOnXamlThread([this]() {
ComPtr<IInputPaneStatics> statics;
if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(),
&statics))) {
qWarning("failed to retrieve input pane statics.");
return S_OK;
}
ComPtr<IInputPane> inputPane;
statics->GetForCurrentView(&inputPane);
if (inputPane) {
QEventDispatcherWinRT::runOnXamlThread([this, inputPane]() {
ComPtr<IInputPane> inputPane;
statics->GetForCurrentView(&inputPane);
if (inputPane) {
EventRegistrationToken showToken, hideToken;
inputPane->add_Showing(Callback<InputPaneVisibilityHandler>(
this, &QWinRTInputContext::onShowing).Get(), &showToken);
inputPane->add_Hiding(Callback<InputPaneVisibilityHandler>(
this, &QWinRTInputContext::onHiding).Get(), &hideToken);
return S_OK;
});
m_keyboardRect = getInputPaneRect(inputPane, m_screen->scaleFactor());
m_isInputPanelVisible = !m_keyboardRect.isEmpty();
} else {
qWarning("failed to retrieve InputPane.");
}
m_keyboardRect = getInputPaneRect(inputPane, m_screen->scaleFactor());
m_isInputPanelVisible = !m_keyboardRect.isEmpty();
} else {
qWarning("failed to retrieve InputPane.");
}
return S_OK;
});
connect(QGuiApplication::inputMethod(), &QInputMethod::cursorRectangleChanged,
this, &QWinRTInputContext::updateScreenCursorRect);
}

View File

@ -173,7 +173,7 @@ QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a,
// qDebug() << "mimeConvertDataToFormat" << format << atomName << data;
if (!encoding.isEmpty()
&& atomName == format + QLatin1String(";charset=") + QString::fromLatin1(encoding)) {
&& atomName == format + QLatin1String(";charset=") + QLatin1String(encoding)) {
#ifndef QT_NO_TEXTCODEC
if (requestedType == QVariant::String) {

View File

@ -1665,7 +1665,8 @@ QString QDB2Driver::formatValue(const QSqlField &field, bool trimStrings) const
}
case QVariant::ByteArray: {
QByteArray ba = field.value().toByteArray();
QString res = QString::fromLatin1("BLOB(X'");
QString res;
res += QLatin1String("BLOB(X'");
static const char hexchars[] = "0123456789abcdef";
for (int i = 0; i < ba.size(); ++i) {
uchar s = (uchar) ba[i];

View File

@ -334,7 +334,7 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer)
QString caption = QCoreApplication::translate("QPrintPreviewDialog", "Print Preview");
if (!printer->docName().isEmpty())
caption += QString::fromLatin1(": ") + printer->docName();
caption += QLatin1String(": ") + printer->docName();
q->setWindowTitle(caption);
if (!printer->isValid()

View File

@ -43,6 +43,8 @@
#include <QtSql/qtsqlglobal.h>
#include <QtSql/qsqltablemodel.h>
#include <QtCore/qtypeinfo.h>
QT_BEGIN_NAMESPACE
@ -53,17 +55,26 @@ public:
QSqlRelation(const QString &aTableName, const QString &indexCol,
const QString &displayCol)
: tName(aTableName), iColumn(indexCol), dColumn(displayCol) {}
void swap(QSqlRelation &other) Q_DECL_NOTHROW
{
qSwap(tName, other.tName);
qSwap(iColumn, other.iColumn);
qSwap(dColumn, other.dColumn);
}
inline QString tableName() const
{ return tName; }
inline QString indexColumn() const
{ return iColumn; }
inline QString displayColumn() const
{ return dColumn; }
inline bool isValid() const
bool isValid() const Q_DECL_NOTHROW
{ return !(tName.isEmpty() || iColumn.isEmpty() || dColumn.isEmpty()); }
private:
QString tName, iColumn, dColumn;
};
Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QSqlRelation)
class QSqlRelationalTableModelPrivate;

View File

@ -696,9 +696,9 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym
next = arg.at(0);
}
Symbol last = expansion.constLast();
if (!expansion.isEmpty() && last.token == s.token && last.token != STRING_LITERAL) {
expansion.pop_back();
if (!expansion.isEmpty() && expansion.constLast().token == s.token
&& expansion.constLast().token != STRING_LITERAL) {
Symbol last = expansion.takeLast();
QByteArray lexem = last.lexem() + next.lexem();
expansion += Symbol(lineNum, last.token, lexem);

View File

@ -830,7 +830,7 @@ QString QAccessibleTextWidget::attributes(int offset, int *startOffset, int *end
family = family.replace('=', QLatin1String("\\="));
family = family.replace(';', QLatin1String("\\;"));
family = family.replace('\"', QLatin1String("\\\""));
attrs["font-family"] = QString::fromLatin1("\"%1\"").arg(family);
attrs["font-family"] = QLatin1Char('"') + family + QLatin1Char('"');
}
int fontSize = int(charFormatFont.pointSize());

View File

@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE
*/
static QString qt_strippedText(QString s)
{
s.remove( QString::fromLatin1("...") );
s.remove(QStringLiteral("..."));
for (int i = 0; i < s.size(); ++i) {
if (s.at(i) == QLatin1Char('&'))
s.remove(i, 1);

View File

@ -97,6 +97,7 @@
#include <private/qstyleanimation_p.h>
#include <qpa/qplatformfontdatabase.h>
#include <qpa/qplatformtheme.h>
#include <QtGui/private/qcoregraphics_p.h>
QT_USE_NAMESPACE
@ -521,47 +522,6 @@ static QString qt_mac_removeMnemonics(const QString &original)
return returnText;
}
static CGContextRef qt_mac_cg_context(const QPaintDevice *pdev);
namespace {
class QMacCGContext
{
CGContextRef context;
public:
QMacCGContext(QPainter *p);
inline QMacCGContext() { context = 0; }
inline QMacCGContext(const QPaintDevice *pdev) {
context = qt_mac_cg_context(pdev);
}
inline QMacCGContext(CGContextRef cg, bool takeOwnership=false) {
context = cg;
if (!takeOwnership)
CGContextRetain(context);
}
inline QMacCGContext(const QMacCGContext &copy) : context(0) { *this = copy; }
inline ~QMacCGContext() {
if (context)
CGContextRelease(context);
}
inline bool isNull() const { return context; }
inline operator CGContextRef() { return context; }
inline QMacCGContext &operator=(const QMacCGContext &copy) {
if (context)
CGContextRelease(context);
context = copy.context;
CGContextRetain(context);
return *this;
}
inline QMacCGContext &operator=(CGContextRef cg) {
if (context)
CGContextRelease(context);
context = cg;
CGContextRetain(context); //we do not take ownership
return *this;
}
};
} // anonymous namespace
OSStatus qt_mac_shape2QRegionHelper(int inMessage, HIShapeRef, const CGRect *inRect, void *inRefcon)
{
QRegion *region = static_cast<QRegion *>(inRefcon);
@ -582,7 +542,6 @@ OSStatus qt_mac_shape2QRegionHelper(int inMessage, HIShapeRef, const CGRect *inR
return noErr;
}
/*!
\internal
Create's a mutable shape, it's the caller's responsibility to release.
@ -612,86 +571,6 @@ QRegion qt_mac_fromHIShapeRef(HIShapeRef shape)
return returnRegion;
}
CGColorSpaceRef m_genericColorSpace = 0;
static QHash<CGDirectDisplayID, CGColorSpaceRef> m_displayColorSpaceHash;
bool m_postRoutineRegistered = false;
static CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget);
static CGColorSpaceRef qt_mac_genericColorSpace()
{
#if 0
if (!m_genericColorSpace) {
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
} else
{
m_genericColorSpace = CGColorSpaceCreateDeviceRGB();
}
if (!m_postRoutineRegistered) {
m_postRoutineRegistered = true;
qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces);
}
}
return m_genericColorSpace;
#else
// Just return the main display colorspace for the moment.
return qt_mac_displayColorSpace(0);
#endif
}
static void qt_mac_cleanUpMacColorSpaces()
{
if (m_genericColorSpace) {
CFRelease(m_genericColorSpace);
m_genericColorSpace = 0;
}
QHash<CGDirectDisplayID, CGColorSpaceRef>::const_iterator it = m_displayColorSpaceHash.constBegin();
while (it != m_displayColorSpaceHash.constEnd()) {
if (it.value())
CFRelease(it.value());
++it;
}
m_displayColorSpaceHash.clear();
}
/*
Ideally, we should pass the widget in here, and use CGGetDisplaysWithRect() etc.
to support multiple displays correctly.
*/
static CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget)
{
CGColorSpaceRef colorSpace;
CGDirectDisplayID displayID;
if (widget == 0) {
displayID = CGMainDisplayID();
} else {
displayID = CGMainDisplayID();
/*
### get correct display
const QRect &qrect = widget->window()->geometry();
CGRect rect = CGRectMake(qrect.x(), qrect.y(), qrect.width(), qrect.height());
CGDisplayCount throwAway;
CGDisplayErr dErr = CGGetDisplaysWithRect(rect, 1, &displayID, &throwAway);
if (dErr != kCGErrorSuccess)
return macDisplayColorSpace(0); // fall back on main display
*/
}
if ((colorSpace = m_displayColorSpaceHash.value(displayID)))
return colorSpace;
colorSpace = CGDisplayCopyColorSpace(displayID);
if (colorSpace == 0)
colorSpace = CGColorSpaceCreateDeviceRGB();
m_displayColorSpaceHash.insert(displayID, colorSpace);
if (!m_postRoutineRegistered) {
m_postRoutineRegistered = true;
qAddPostRoutine(qt_mac_cleanUpMacColorSpaces);
}
return colorSpace;
}
bool qt_macWindowIsTextured(const QWidget *window)
{
if (QWindow *w = window->windowHandle())
@ -2284,7 +2163,7 @@ void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush
painter->setClipRegion(rgn);
QCFType<CGContextRef> cg = qt_mac_cg_context(target);
QMacCGContext cg(target);
CGContextSaveGState(cg);
HIThemeSetFill(kThemeBrushDialogBackgroundActive, 0, cg, kHIThemeOrientationInverted);
@ -2358,7 +2237,7 @@ void QMacStyle::polish(QWidget* w)
mtinfo.menuType = kThemeMenuTypePopUp;
// HIRect rect = CGRectMake(0, 0, px.width(), px.height());
// ###
//HIThemeDrawMenuBackground(&rect, &mtinfo, QCFType<CGContextRef>(qt_mac_cg_context(&px)),
//HIThemeDrawMenuBackground(&rect, &mtinfo, QMacCGContext(&px)),
// kHIThemeOrientationNormal);
QPalette pal = w->palette();
QBrush background(px);
@ -7189,158 +7068,6 @@ int QMacStyle::layoutSpacing(QSizePolicy::ControlType control1,
return_SIZE(10, 8, 6); // guess
}
static void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform)
{
CGAffineTransform old_xform = CGAffineTransformIdentity;
if (orig_xform) { //setup xforms
old_xform = CGContextGetCTM(hd);
CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform));
CGContextConcatCTM(hd, *orig_xform);
}
//do the clipping
CGContextBeginPath(hd);
if (rgn.isEmpty()) {
CGContextAddRect(hd, CGRectMake(0, 0, 0, 0));
} else {
QCFType<HIMutableShapeRef> shape = qt_mac_toHIMutableShape(rgn);
Q_ASSERT(!HIShapeIsEmpty(shape));
HIShapeReplacePathInCGContext(shape, hd);
}
CGContextClip(hd);
if (orig_xform) {//reset xforms
CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd)));
CGContextConcatCTM(hd, old_xform);
}
}
// move to QRegion?
void qt_mac_scale_region(QRegion *region, qreal scaleFactor)
{
if (!region || !region->rectCount())
return;
QVector<QRect> scaledRects;
scaledRects.reserve(region->rectCount());
for (const QRect &rect : *region)
scaledRects.append(QRect(rect.topLeft() * scaleFactor, rect.size() * scaleFactor));
region->setRects(&scaledRects[0], scaledRects.count());
}
static CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice);
namespace {
QMacCGContext::QMacCGContext(QPainter *p)
{
QPaintEngine *pe = p->paintEngine();
pe->syncState();
context = 0;
int devType = p->device()->devType();
if (pe->type() == QPaintEngine::Raster
&& (devType == QInternal::Widget ||
devType == QInternal::Pixmap ||
devType == QInternal::Image)) {
CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pe->paintDevice());
uint flags = kCGImageAlphaPremultipliedFirst;
flags |= kCGBitmapByteOrder32Host;
const QImage *image = (const QImage *) pe->paintDevice();
context = CGBitmapContextCreate((void *) image->bits(), image->width(), image->height(),
8, image->bytesPerLine(), colorspace, flags);
// Invert y axis.
CGContextTranslateCTM(context, 0, image->height());
CGContextScaleCTM(context, 1, -1);
const qreal devicePixelRatio = image->devicePixelRatio();
if (devType == QInternal::Widget) {
// Set the clip rect which is an intersection of the system clip
// and the painter clip. To make matters more interesting these
// are in device pixels and device-independent pixels, respectively.
QRegion clip = p->paintEngine()->systemClip(); // get system clip in device pixels
QTransform native = p->deviceTransform(); // get device transform. dx/dy is in device pixels
if (p->hasClipping()) {
QRegion r = p->clipRegion(); // get painter clip, which is in device-independent pixels
qt_mac_scale_region(&r, devicePixelRatio); // scale painter clip to device pixels
r.translate(native.dx(), native.dy());
if (clip.isEmpty())
clip = r;
else
clip &= r;
}
qt_mac_clip_cg(context, clip, 0); // clip in device pixels
// Scale the context so that painting happens in device-independet pixels.
CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
CGContextTranslateCTM(context, native.dx() / devicePixelRatio, native.dy() / devicePixelRatio);
} else {
// Scale to paint in device-independent pixels.
CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
}
} else {
qDebug() << "QMacCGContext:: Unsupported painter devtype type" << devType;
}
}
} // anonymous namespace
static CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice)
{
bool isWidget = (paintDevice->devType() == QInternal::Widget);
return qt_mac_displayColorSpace(isWidget ? static_cast<const QWidget *>(paintDevice) : 0);
}
/*! \internal
Returns the CoreGraphics CGContextRef of the paint device. 0 is
returned if it can't be obtained. It is the caller's responsibility to
CGContextRelease the context when finished using it.
\warning This function is only available on \macos.
\warning This function is duplicated in the Cocoa platform plugin.
*/
CGContextRef qt_mac_cg_context(const QPaintDevice *pdev)
{
if (pdev->devType() == QInternal::Pixmap) {
const QPixmap *pm = static_cast<const QPixmap*>(pdev);
CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev);
uint flags = kCGImageAlphaPremultipliedFirst;
flags |= kCGBitmapByteOrder32Host;
CGContextRef ret = 0;
QPlatformPixmap *data = const_cast<QPixmap *>(pm)->data_ptr().data();
if (data->classId() == QPlatformPixmap::RasterClass) {
QImage *image = data->buffer();
ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(),
8, image->bytesPerLine(), colorspace, flags);
} else {
qDebug("qt_mac_cg_context: Unsupported pixmap class");
}
CGContextTranslateCTM(ret, 0, pm->height());
qreal devicePixelRatio = pdev->devicePixelRatioF();
CGContextScaleCTM(ret, devicePixelRatio, devicePixelRatio);
CGContextScaleCTM(ret, 1, -1);
return ret;
} else if (pdev->devType() == QInternal::Widget) {
//CGContextRef ret = static_cast<CGContextRef>(static_cast<const QWidget *>(pdev)->macCGHandle());
///CGContextRetain(ret);
//return ret;
qDebug("qt_mac_cg_context: not implemented: Widget class");
return 0;
}
return 0;
}
/*
FontHash::FontHash()
{

View File

@ -188,8 +188,8 @@ static QString int2string(int num, int base, int ndigits, bool *oflow)
} while (n != 0);
len = ndigits - len;
if (len > 0)
s.fill(QLatin1Char(' '), len);
s += QString::fromLatin1(p);
s += QString(len, QLatin1Char(' '));
s += QLatin1String(p);
}
break;
}

View File

@ -415,7 +415,7 @@ QSize QPushButton::sizeHint() const
QString s(text());
bool empty = s.isEmpty();
if (empty)
s = QString::fromLatin1("XXXX");
s = QStringLiteral("XXXX");
QFontMetrics fm = fontMetrics();
QSize sz = fm.size(Qt::TextShowMnemonic, s);
if(!empty || !w)

View File

@ -41,7 +41,6 @@
#include <QtCore/QStandardPaths>
#include <QtCore/QTemporaryDir>
#include <QtCore/QTextStream>
#include <QFutureSynchronizer>
#include <QtConcurrent/QtConcurrentRun>
#include <QtTest/QtTest>
@ -844,18 +843,18 @@ void tst_QMimeDatabase::findByFile()
void tst_QMimeDatabase::fromThreads()
{
QThreadPool::globalInstance()->setMaxThreadCount(20);
QThreadPool tp;
tp.setMaxThreadCount(20);
// Note that data-based tests cannot be used here (QTest::fetchData asserts).
QFutureSynchronizer<void> sync;
sync.addFuture(QtConcurrent::run(this, &tst_QMimeDatabase::mimeTypeForName));
sync.addFuture(QtConcurrent::run(this, &tst_QMimeDatabase::aliases));
sync.addFuture(QtConcurrent::run(this, &tst_QMimeDatabase::allMimeTypes));
sync.addFuture(QtConcurrent::run(this, &tst_QMimeDatabase::icons));
sync.addFuture(QtConcurrent::run(this, &tst_QMimeDatabase::inheritance));
sync.addFuture(QtConcurrent::run(this, &tst_QMimeDatabase::knownSuffix));
sync.addFuture(QtConcurrent::run(this, &tst_QMimeDatabase::mimeTypeForFileWithContent));
sync.addFuture(QtConcurrent::run(this, &tst_QMimeDatabase::allMimeTypes)); // a second time
// sync dtor blocks waiting for finished
QtConcurrent::run(&tp, this, &tst_QMimeDatabase::mimeTypeForName);
QtConcurrent::run(&tp, this, &tst_QMimeDatabase::aliases);
QtConcurrent::run(&tp, this, &tst_QMimeDatabase::allMimeTypes);
QtConcurrent::run(&tp, this, &tst_QMimeDatabase::icons);
QtConcurrent::run(&tp, this, &tst_QMimeDatabase::inheritance);
QtConcurrent::run(&tp, this, &tst_QMimeDatabase::knownSuffix);
QtConcurrent::run(&tp, this, &tst_QMimeDatabase::mimeTypeForFileWithContent);
QtConcurrent::run(&tp, this, &tst_QMimeDatabase::allMimeTypes); // a second time
QVERIFY(tp.waitForDone(60000));
}
#ifndef QT_NO_PROCESS

View File

@ -341,6 +341,7 @@ void tst_QStringList::join() const
QFETCH(QString, expectedResult);
QCOMPARE(input.join(separator), expectedResult);
QCOMPARE(input.join(QLatin1String(separator.toLatin1())), expectedResult);
}
void tst_QStringList::join_data() const

View File

@ -26,6 +26,7 @@
**
****************************************************************************/
#include <QtCore/QTemporaryDir>
#include <QtTest/QtTest>
#include <QtGui/qevent.h>
@ -38,6 +39,7 @@ public:
public slots:
void initTestCase();
void cleanupTestCase();
private slots:
void constructor();
@ -54,6 +56,9 @@ private:
bool appendFileContent(QFileOpenEvent& event, const QByteArray& writeContent);
bool event(QEvent *);
QTemporaryDir m_temporaryDir;
QString m_originalCurrent;
};
tst_qfileopenevent::~tst_qfileopenevent()
@ -62,6 +67,13 @@ tst_qfileopenevent::~tst_qfileopenevent()
void tst_qfileopenevent::initTestCase()
{
m_originalCurrent = QDir::currentPath();
QDir::setCurrent(m_temporaryDir.path());
}
void tst_qfileopenevent::cleanupTestCase()
{
QDir::setCurrent(m_originalCurrent);
}
void tst_qfileopenevent::createFile(const QString &filename, const QByteArray &content)

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