Merge "Merge remote-tracking branch 'origin/5.8' into dev" into refs/staging/dev
This commit is contained in:
commit
abbc5ecc5e
@ -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";
|
||||
|
||||
|
@ -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)
|
||||
|
2
src/3rdparty/freetype/freetype.pro
vendored
2
src/3rdparty/freetype/freetype.pro
vendored
@ -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)
|
||||
|
||||
|
@ -1455,4 +1455,9 @@ public class QtActivityDelegate
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
|
||||
{
|
||||
QtNative.sendRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -37,8 +37,4 @@ HEADERS += \
|
||||
# private headers
|
||||
HEADERS += \
|
||||
|
||||
qtConfig(clock-gettime) {
|
||||
linux-*|hpux-*|solaris-*: LIBS_PRIVATE *= -lrt
|
||||
}
|
||||
|
||||
load(qt_module)
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 \
|
||||
|
566
src/gui/painting/qcoregraphics.mm
Normal file
566
src/gui/painting/qcoregraphics.mm
Normal 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
|
121
src/gui/painting/qcoregraphics_p.h
Normal file
121
src/gui/painting/qcoregraphics_p.h
Normal 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 ©) : context(0) { *this = copy; }
|
||||
inline ~QMacCGContext() {
|
||||
if (context)
|
||||
CGContextRelease(context);
|
||||
}
|
||||
inline bool isNull() const { return context; }
|
||||
inline operator CGContextRef() { return context; }
|
||||
inline QMacCGContext &operator=(const QMacCGContext ©) {
|
||||
if (context)
|
||||
CGContextRelease(context);
|
||||
context = copy.context;
|
||||
CGContextRetain(context);
|
||||
return *this;
|
||||
}
|
||||
inline QMacCGContext &operator=(CGContextRef cg) {
|
||||
if (context)
|
||||
CGContextRelease(context);
|
||||
context = cg;
|
||||
CGContextRetain(context); //we do not take ownership
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
CGContextRef context;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QCOREGRAPHICS_P_H
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -87,10 +87,10 @@ public:
|
||||
BackgroundRequestAttribute,
|
||||
SpdyAllowedAttribute,
|
||||
SpdyWasUsedAttribute,
|
||||
HTTP2AllowedAttribute,
|
||||
HTTP2WasUsedAttribute,
|
||||
EmitAllUploadProgressSignalsAttribute,
|
||||
FollowRedirectsAttribute,
|
||||
HTTP2AllowedAttribute,
|
||||
HTTP2WasUsedAttribute,
|
||||
OriginalContentLengthAttribute,
|
||||
|
||||
User = 1000,
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -62,13 +62,16 @@ public:
|
||||
QRasterBackingStore(QWindow *window);
|
||||
~QRasterBackingStore();
|
||||
|
||||
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
|
||||
QImage toImage() const Q_DECL_OVERRIDE;
|
||||
void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE;
|
||||
void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE;
|
||||
bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
|
||||
void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE;
|
||||
|
||||
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
|
||||
QImage toImage() const Q_DECL_OVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual QImage::Format format() const;
|
||||
|
||||
QImage m_image;
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 ®ion, const QPoint &offset) Q_DECL_OVERRIDE;
|
||||
QImage toImage() const Q_DECL_OVERRIDE;
|
||||
|
||||
void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE;
|
||||
bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
|
||||
void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE;
|
||||
qreal getBackingStoreDevicePixelRatio();
|
||||
void flush(QWindow *, const QRegion &, const QPoint &) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
QImage m_qImage;
|
||||
QSize m_requestedSize;
|
||||
QImage::Format format() const Q_DECL_OVERRIDE;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -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 ®ion, const QPoint &offset)
|
||||
void QCocoaBackingStore::flush(QWindow *window, const QRegion ®ion, 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 ®ion)
|
||||
{
|
||||
if (m_qImage.hasAlphaChannel()) {
|
||||
QPainter p(&m_qImage);
|
||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
const QColor blank = Qt::transparent;
|
||||
for (const QRect &rect : region)
|
||||
p.fillRect(rect, blank);
|
||||
}
|
||||
}
|
||||
|
||||
qreal QCocoaBackingStore::getBackingStoreDevicePixelRatio()
|
||||
{
|
||||
return m_qImage.devicePixelRatio();
|
||||
if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle()))
|
||||
[cocoaWindow->m_qtView flushBackingStore:this region:region offset:offset];
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "qcocoacursor.h"
|
||||
#include "qcocoawindow.h"
|
||||
#include "qcocoahelpers.h"
|
||||
#include <QtGui/private/qcoregraphics_p.h>
|
||||
|
||||
#include <QtGui/QBitmap>
|
||||
|
||||
|
@ -43,6 +43,7 @@
|
||||
#ifndef QT_NO_WIDGETS
|
||||
#include <QtWidgets/qwidget.h>
|
||||
#endif
|
||||
#include <QtGui/private/qcoregraphics_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -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 ®ion);
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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 ®ion)
|
||||
{
|
||||
HIMutableShapeRef shape = HIShapeCreateMutable();
|
||||
for (const QRect &rect : region) {
|
||||
CGRect cgRect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
|
||||
HIShapeUnionWithRect(shape, &cgRect);
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
QColor qt_mac_toQColor(const NSColor *color)
|
||||
{
|
||||
QColor qtColor;
|
||||
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
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -64,6 +64,8 @@
|
||||
#include <qpa/qplatformprintersupport.h>
|
||||
#endif
|
||||
|
||||
#include <QtGui/private/qcoregraphics_p.h>
|
||||
|
||||
#include <QtPlatformHeaders/qcocoawindowfunctions.h>
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -86,6 +86,7 @@
|
||||
|
||||
#include "qt_mac_p.h"
|
||||
#include "qcocoahelpers.h"
|
||||
#include <QtGui/private/qcoregraphics_p.h>
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -90,44 +90,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class QMacCGContext
|
||||
{
|
||||
CGContextRef context;
|
||||
public:
|
||||
QMacCGContext(QPainter *p); //qpaintengine_mac.mm
|
||||
inline QMacCGContext() { context = 0; }
|
||||
inline QMacCGContext(QPaintDevice *pdev) {
|
||||
extern CGContextRef qt_mac_cg_context(QPaintDevice *);
|
||||
context = qt_mac_cg_context(pdev);
|
||||
}
|
||||
inline QMacCGContext(CGContextRef cg, bool takeOwnership=false) {
|
||||
context = cg;
|
||||
if(!takeOwnership)
|
||||
CGContextRetain(context);
|
||||
}
|
||||
inline QMacCGContext(const QMacCGContext ©) : context(0) { *this = copy; }
|
||||
inline ~QMacCGContext() {
|
||||
if(context)
|
||||
CGContextRelease(context);
|
||||
}
|
||||
inline bool isNull() const { return context; }
|
||||
inline operator CGContextRef() { return context; }
|
||||
inline QMacCGContext &operator=(const QMacCGContext ©) {
|
||||
if(context)
|
||||
CGContextRelease(context);
|
||||
context = copy.context;
|
||||
CGContextRetain(context);
|
||||
return *this;
|
||||
}
|
||||
inline QMacCGContext &operator=(CGContextRef cg) {
|
||||
if(context)
|
||||
CGContextRelease(context);
|
||||
context = cg;
|
||||
CGContextRetain(context); //we do not take ownership
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class QMacInternalPasteboardMime;
|
||||
class QMimeData;
|
||||
|
||||
|
@ -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")) {
|
||||
|
@ -49,6 +49,8 @@
|
||||
|
||||
#include <QtDebug>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QIOSPaintDevice : public QOpenGLPaintDevice
|
||||
{
|
||||
public:
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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() :
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -163,7 +163,7 @@
|
||||
|
||||
@implementation QIOSTextInputResponder
|
||||
|
||||
- (id)initWithInputContext:(QIOSInputContext *)inputContext
|
||||
- (id)initWithInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)inputContext
|
||||
{
|
||||
if (!(self = [self init]))
|
||||
return self;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -48,10 +48,10 @@
|
||||
class QIOSContext;
|
||||
class QIOSWindow;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@class QUIView;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QIOSWindow : public QObject, public QPlatformWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -54,6 +54,8 @@
|
||||
|
||||
#include <QtDebug>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QIOSWindow::QIOSWindow(QWindow *window)
|
||||
: QPlatformWindow(window)
|
||||
, m_view([[QUIView alloc] initWithQIOSWindow:this])
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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];
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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 ©) : context(0) { *this = copy; }
|
||||
inline ~QMacCGContext() {
|
||||
if (context)
|
||||
CGContextRelease(context);
|
||||
}
|
||||
inline bool isNull() const { return context; }
|
||||
inline operator CGContextRef() { return context; }
|
||||
inline QMacCGContext &operator=(const QMacCGContext ©) {
|
||||
if (context)
|
||||
CGContextRelease(context);
|
||||
context = copy.context;
|
||||
CGContextRetain(context);
|
||||
return *this;
|
||||
}
|
||||
inline QMacCGContext &operator=(CGContextRef cg) {
|
||||
if (context)
|
||||
CGContextRelease(context);
|
||||
context = cg;
|
||||
CGContextRetain(context); //we do not take ownership
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
OSStatus qt_mac_shape2QRegionHelper(int inMessage, HIShapeRef, const CGRect *inRect, void *inRefcon)
|
||||
{
|
||||
QRegion *region = static_cast<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()
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user