Merge remote-tracking branch 'origin/5.3' into dev

Conflicts:
	src/gui/text/qfontengine_qpf2.cpp

Change-Id: Ib04f92c41d0edd55d3aef8fb1708d917fba0f2a8
This commit is contained in:
Frederik Gladhorn 2014-07-14 10:35:51 +02:00
commit 7c495cfea9
21 changed files with 204 additions and 252 deletions

View File

@ -453,6 +453,7 @@ public class QtActivityDelegate
m_environmentVariables = loaderParams.getString(ENVIRONMENT_VARIABLES_KEY);
String additionalEnvironmentVariables = "QT_ANDROID_FONTS_MONOSPACE=Droid Sans Mono;Droid Sans;Droid Sans Fallback"
+ "\tQT_ANDROID_FONTS_SERIF=Droid Serif"
+ "\tNECESSITAS_API_LEVEL=" + necessitasApiLevel
+ "\tHOME=" + m_activity.getFilesDir().getAbsolutePath()
+ "\tTMPDIR=" + m_activity.getFilesDir().getAbsolutePath();

View File

@ -90,7 +90,7 @@ static void writeTextStream_snippet()
//! [2]
}
static void writeTextStream_snippet()
static void writeDataStream_snippet()
{
QFile file("out.dat");
if (!file.open(QIODevice::WriteOnly))

View File

@ -530,7 +530,8 @@
# define Q_COMPILER_NOEXCEPT
# endif
# if __INTEL_COMPILER >= 1400
# define Q_COMPILER_CONSTEXPR
// causes issues with QArrayData and QtPrivate::RefCount - Intel issue ID 6000056211, bug DPD200534796
//# define Q_COMPILER_CONSTEXPR
# define Q_COMPILER_DELEGATING_CONSTRUCTORS
# define Q_COMPILER_EXPLICIT_CONVERSIONS
# define Q_COMPILER_EXPLICIT_OVERRIDES

View File

@ -596,7 +596,7 @@ struct QtFontDesc
static int match(int script, const QFontDef &request,
const QString &family_name, const QString &foundry_name, int force_encoding_id,
QtFontDesc *desc, const QList<int> &blacklisted);
QtFontDesc *desc, const QList<int> &blacklisted, bool fallback);
static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef, bool multi)
{
@ -1079,7 +1079,7 @@ static bool matchFamilyName(const QString &familyName, QtFontFamily *f)
*/
static int match(int script, const QFontDef &request,
const QString &family_name, const QString &foundry_name, int force_encoding_id,
QtFontDesc *desc, const QList<int> &blacklistedFamilies)
QtFontDesc *desc, const QList<int> &blacklistedFamilies, bool fallback = false)
{
Q_UNUSED(force_encoding_id);
int result = -1;
@ -1132,7 +1132,7 @@ static int match(int script, const QFontDef &request,
load(test.family->name, script);
// Check if family is supported in the script we want
if (script != QChar::Script_Common && !(test.family->writingSystems[writingSystem] & QtFontFamily::Supported))
if (!fallback && script != QChar::Script_Common && !(test.family->writingSystems[writingSystem] & QtFontFamily::Supported))
continue;
// as we know the script is supported, we can be sure
@ -2450,7 +2450,7 @@ bool QFontDatabase::supportsThreadedFontRendering()
*/
QFontEngine *
QFontDatabase::findFont(int script, const QFontPrivate *fp,
const QFontDef &request, bool multi)
const QFontDef &request, bool multi, bool fallback)
{
QMutexLocker locker(fontDatabaseMutex());
@ -2478,7 +2478,7 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp,
QtFontDesc desc;
QList<int> blackListed;
int index = match(script, request, family_name, foundry_name, force_encoding_id, &desc, blackListed);
int index = match(script, request, family_name, foundry_name, force_encoding_id, &desc, blackListed, fallback);
if (index >= 0) {
engine = loadEngine(script, request, desc.family, desc.foundry, desc.style, desc.size);
if (!engine)

View File

@ -160,7 +160,7 @@ private:
static void createDatabase();
static void parseFontName(const QString &name, QString &foundry, QString &family);
static QString resolveFontFamilyAlias(const QString &family);
static QFontEngine *findFont(int script, const QFontPrivate *fp, const QFontDef &request, bool multi = false);
static QFontEngine *findFont(int script, const QFontPrivate *fp, const QFontDef &request, bool multi = false, bool fallback = false);
static void load(const QFontPrivate *d, int script);
friend struct QFontDef;

View File

@ -2045,7 +2045,7 @@ void QFontEngineMultiBasicImpl::loadEngine(int at)
request.family = fallbackFamilies.at(at-1);
engines[at] = QFontDatabase::findFont(script,
/*fontprivate = */0,
request, /*multi = */false);
request, /*multi = */false, true);
Q_ASSERT(engines[at]);
engines[at]->ref.ref();
engines[at]->fontDef = request;

View File

@ -55,126 +55,32 @@
****************************************************************************/
#include "qsslsocket_openssl_p.h"
#include <jni.h>
#include <android/log.h>
static JavaVM *javaVM = 0;
static jclass appClass;
static jmethodID getSslCertificatesMethodID;
struct AttachedJNIEnv
{
AttachedJNIEnv()
{
attached = false;
if (javaVM->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) < 0) {
if (javaVM->AttachCurrentThread(&jniEnv, NULL) < 0) {
__android_log_print(ANDROID_LOG_ERROR, "Qt", "AttachCurrentThread failed");
jniEnv = 0;
return;
}
attached = true;
}
}
~AttachedJNIEnv()
{
if (attached)
javaVM->DetachCurrentThread();
}
bool attached;
JNIEnv *jniEnv;
};
static const char logTag[] = "Qt";
static const char classErrorMsg[] = "Can't find class \"%s\"";
static const char methodErrorMsg[] = "Can't find method \"%s%s\"";
#define FIND_AND_CHECK_CLASS(CLASS_NAME) \
clazz = env->FindClass(CLASS_NAME); \
if (!clazz) { \
__android_log_print(ANDROID_LOG_FATAL, logTag, classErrorMsg, CLASS_NAME); \
return JNI_FALSE; \
}
#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
if (!VAR) { \
__android_log_print(ANDROID_LOG_FATAL, logTag, methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \
return JNI_FALSE; \
}
static bool registerNatives(JNIEnv *env)
{
jclass clazz;
FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/QtNative");
appClass = static_cast<jclass>(env->NewGlobalRef(clazz));
#if 0 //we don't call C++ functions from Java at this time
if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
__android_log_print(ANDROID_LOG_FATAL, logTag, "RegisterNatives failed");
return JNI_FALSE;
}
#endif
GET_AND_CHECK_STATIC_METHOD(getSslCertificatesMethodID, appClass, "getSSLCertificates", "()[[B");
return true;
}
Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/)
{
typedef union {
JNIEnv *nativeEnvironment;
void *venv;
} UnionJNIEnvToVoid;
__android_log_print(ANDROID_LOG_INFO, logTag, "Network start");
UnionJNIEnvToVoid uenv;
uenv.venv = NULL;
javaVM = 0;
if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
__android_log_print(ANDROID_LOG_FATAL, logTag, "GetEnv failed");
return -1;
}
JNIEnv *env = uenv.nativeEnvironment;
if (!registerNatives(env)) {
__android_log_print(ANDROID_LOG_FATAL, logTag, "registerNatives failed");
return -1;
}
javaVM = vm;
return JNI_VERSION_1_4;
}
#include <QtCore/private/qjni_p.h>
QT_BEGIN_NAMESPACE
QList<QByteArray> QSslSocketPrivate::fetchSslCertificateData()
{
QList<QByteArray> certificateData;
AttachedJNIEnv env;
if (env.jniEnv) {
jobjectArray jcertificates =
static_cast<jobjectArray>(env.jniEnv->CallStaticObjectMethod(appClass, getSslCertificatesMethodID));
jint nCertificates = env.jniEnv->GetArrayLength(jcertificates);
QJNIObjectPrivate certificates = QJNIObjectPrivate::callStaticObjectMethod("org/qtproject/qt5/android/QtNative",
"getSSLCertificates",
"()[[B");
if (!certificates.isValid())
return certificateData;
for (int i = 0; i < nCertificates; ++i) {
jbyteArray jCert = static_cast<jbyteArray>(env.jniEnv->GetObjectArrayElement(jcertificates, i));
QJNIEnvironmentPrivate env;
jobjectArray jcertificates = static_cast<jobjectArray>(certificates.object());
const jint nCertificates = env->GetArrayLength(jcertificates);
const uint sz = env.jniEnv->GetArrayLength(jCert);
jbyte *buffer = env.jniEnv->GetByteArrayElements(jCert, 0);
certificateData.append(QByteArray(reinterpret_cast<char*>(buffer), sz));
for (int i = 0; i < nCertificates; ++i) {
jbyteArray jCert = static_cast<jbyteArray>(env->GetObjectArrayElement(jcertificates, i));
const uint sz = env->GetArrayLength(jCert);
jbyte *buffer = env->GetByteArrayElements(jCert, 0);
certificateData.append(QByteArray(reinterpret_cast<char*>(buffer), sz));
env.jniEnv->ReleaseByteArrayElements(jCert, buffer, JNI_ABORT); // don't copy back the elements
env.jniEnv->DeleteLocalRef(jCert);
}
env->ReleaseByteArrayElements(jCert, buffer, JNI_ABORT); // don't copy back the elements
env->DeleteLocalRef(jCert);
}
return certificateData;

View File

@ -41,83 +41,39 @@
#include "androidjniclipboard.h"
#include "androidjnimain.h"
#include <QtCore/private/qjni_p.h>
QT_BEGIN_NAMESPACE
using namespace QtAndroid;
namespace QtAndroidClipboard
{
// Clipboard support
static jmethodID m_registerClipboardManagerMethodID = 0;
static jmethodID m_setClipboardTextMethodID = 0;
static jmethodID m_hasClipboardTextMethodID = 0;
static jmethodID m_getClipboardTextMethodID = 0;
// Clipboard support
void setClipboardListener(QAndroidPlatformClipboard *listener)
{
Q_UNUSED(listener);
AttachedJNIEnv env;
if (!env.jniEnv)
return;
env.jniEnv->CallStaticVoidMethod(applicationClass(), m_registerClipboardManagerMethodID);
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "registerClipboardManager");
}
void setClipboardText(const QString &text)
{
AttachedJNIEnv env;
if (!env.jniEnv)
return;
jstring jtext = env.jniEnv->NewString(reinterpret_cast<const jchar *>(text.data()),
text.length());
env.jniEnv->CallStaticVoidMethod(applicationClass(), m_setClipboardTextMethodID, jtext);
env.jniEnv->DeleteLocalRef(jtext);
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
"setClipboardText",
"(Ljava/lang/String;)V",
QJNIObjectPrivate::fromString(text).object());
}
bool hasClipboardText()
{
AttachedJNIEnv env;
if (!env.jniEnv)
return false;
return env.jniEnv->CallStaticBooleanMethod(applicationClass(), m_hasClipboardTextMethodID);
return QJNIObjectPrivate::callStaticMethod<jboolean>(applicationClass(),
"hasClipboardText");
}
QString clipboardText()
{
AttachedJNIEnv env;
if (!env.jniEnv)
return QString();
jstring text = reinterpret_cast<jstring>(env.jniEnv->CallStaticObjectMethod(applicationClass(),
m_getClipboardTextMethodID));
const jchar *jstr = env.jniEnv->GetStringChars(text, 0);
QString str(reinterpret_cast<const QChar *>(jstr), env.jniEnv->GetStringLength(text));
env.jniEnv->ReleaseStringChars(text, jstr);
return str;
}
#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
if (!VAR) { \
__android_log_print(ANDROID_LOG_FATAL, qtTagText(), methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \
return false; \
}
bool registerNatives(JNIEnv *env)
{
jclass appClass = QtAndroid::applicationClass();
GET_AND_CHECK_STATIC_METHOD(m_registerClipboardManagerMethodID, appClass, "registerClipboardManager", "()V");
GET_AND_CHECK_STATIC_METHOD(m_setClipboardTextMethodID, appClass, "setClipboardText", "(Ljava/lang/String;)V");
GET_AND_CHECK_STATIC_METHOD(m_hasClipboardTextMethodID, appClass, "hasClipboardText", "()Z");
GET_AND_CHECK_STATIC_METHOD(m_getClipboardTextMethodID, appClass, "getClipboardText", "()Ljava/lang/String;");
return true;
QJNIObjectPrivate text = QJNIObjectPrivate::callStaticObjectMethod(applicationClass(),
"getClipboardText",
"()Ljava/lang/String;");
return text.toString();
}
}

View File

@ -42,7 +42,6 @@
#ifndef ANDROIDJNICLIPBOARD_H
#define ANDROIDJNICLIPBOARD_H
#include <jni.h>
#include <QString>
QT_BEGIN_NAMESPACE
@ -56,8 +55,6 @@ namespace QtAndroidClipboard
bool hasClipboardText();
QString clipboardText();
// Clipboard support
bool registerNatives(JNIEnv *env);
}
QT_END_NAMESPACE

View File

@ -773,7 +773,6 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
JNIEnv *env = uenv.nativeEnvironment;
if (!registerNatives(env)
|| !QtAndroidInput::registerNatives(env)
|| !QtAndroidClipboard::registerNatives(env)
|| !QtAndroidMenu::registerNatives(env)
|| !QtAndroidAccessibility::registerNatives(env)
|| !QtAndroidDialogHelpers::registerNatives(env)) {

View File

@ -86,6 +86,8 @@ QStringList QAndroidPlatformFontDatabase::fallbacksForFamily(const QString &fami
if (styleHint == QFont::Monospace || styleHint == QFont::Courier)
return QString(qgetenv("QT_ANDROID_FONTS_MONOSPACE")).split(";") + m_fallbacks[script];
else if (styleHint == QFont::Serif)
return QString(qgetenv("QT_ANDROID_FONTS_SERIF")).split(";") + m_fallbacks[script];
return QString(qgetenv("QT_ANDROID_FONTS")).split(";") + m_fallbacks[script];
}

View File

@ -72,9 +72,8 @@ bool QAndroidPlatformOpenGLContext::needsFBOReadBackWorkaroud()
if (!set) {
const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
needsWorkaround =
qstrcmp(rendererString, "Mali-400 MP") == 0
|| qstrcmp(rendererString, "Adreno (TM) 200") == 0
|| qstrcmp(rendererString, "Adreno (TM) 205") == 0
qstrncmp(rendererString, "Mali-4xx", 6) == 0 // Mali-400, Mali-450
|| qstrncmp(rendererString, "Adreno (TM) 2xx", 13) == 0 // Adreno 200, 203, 205
|| qstrcmp(rendererString, "GC1000 core") == 0;
set = true;
}

View File

@ -43,30 +43,21 @@
#include <QUrl>
#include <QDir>
#include <QDebug>
#include <QtCore/private/qjni_p.h>
QT_BEGIN_NAMESPACE
QAndroidPlatformServices::QAndroidPlatformServices()
{
QtAndroid::AttachedJNIEnv env;
if (!env.jniEnv)
return;
m_openURIMethodID = env.jniEnv->GetStaticMethodID(QtAndroid::applicationClass(),
"openURL",
"(Ljava/lang/String;)V");
}
bool QAndroidPlatformServices::openUrl(const QUrl &url)
{
QtAndroid::AttachedJNIEnv env;
if (!env.jniEnv)
return false;
jstring string = env.jniEnv->NewString(reinterpret_cast<const jchar *>(url.toString().constData()),
url.toString().length());
env.jniEnv->CallStaticVoidMethod(QtAndroid::applicationClass(), m_openURIMethodID, string);
env.jniEnv->DeleteLocalRef(string);
QJNIObjectPrivate urlString = QJNIObjectPrivate::fromString(url.toString());
QJNIObjectPrivate::callStaticMethod<void>(QtAndroid::applicationClass(),
"openURL",
"(Ljava/lang/String;)V",
urlString.object());
return true;
}

View File

@ -44,7 +44,6 @@
#include <qpa/qplatformservices.h>
#include "androidjnimain.h"
#include <jni.h>
QT_BEGIN_NAMESPACE
@ -55,9 +54,6 @@ public:
bool openUrl(const QUrl &url);
bool openDocument(const QUrl &url);
QByteArray desktopEnvironment() const;
private:
jmethodID m_openURIMethodID;
};
QT_END_NAMESPACE

View File

@ -508,22 +508,25 @@ private:
int m_xiOpCode, m_xiEventBase, m_xiErrorBase;
#ifndef QT_NO_TABLETEVENT
struct TabletData {
TabletData() : deviceId(0), down(false), serialId(0), inProximity(false) { }
TabletData() : deviceId(0), pointerType(QTabletEvent::UnknownPointer),
tool(QTabletEvent::Stylus), down(false), serialId(0), inProximity(false) { }
int deviceId;
QTabletEvent::PointerType pointerType;
QTabletEvent::TabletDevice tool;
bool down;
qint64 serialId;
bool inProximity;
struct ValuatorClassInfo {
ValuatorClassInfo() : minVal(0), maxVal(0) { }
ValuatorClassInfo() : minVal(0.), maxVal(0.), curVal(0.) { }
double minVal;
double maxVal;
double curVal;
int number;
};
QHash<int, ValuatorClassInfo> valuatorInfo;
};
bool xi2HandleTabletEvent(void *event, TabletData *tabletData);
void xi2ReportTabletEvent(const TabletData &tabletData, void *event);
void xi2ReportTabletEvent(TabletData &tabletData, void *event);
QVector<TabletData> m_tabletData;
#endif
struct ScrollingDevice {

View File

@ -685,6 +685,39 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin
#endif // XCB_USE_XINPUT21
}
static QTabletEvent::TabletDevice toolIdToTabletDevice(quint32 toolId) {
// keep in sync with wacom_intuos_inout() in Linux kernel driver wacom_wac.c
switch (toolId) {
case 0xd12:
case 0x912:
case 0x112:
case 0x913: /* Intuos3 Airbrush */
case 0x91b: /* Intuos3 Airbrush Eraser */
case 0x902: /* Intuos4/5 13HD/24HD Airbrush */
case 0x90a: /* Intuos4/5 13HD/24HD Airbrush Eraser */
case 0x100902: /* Intuos4/5 13HD/24HD Airbrush */
case 0x10090a: /* Intuos4/5 13HD/24HD Airbrush Eraser */
return QTabletEvent::Airbrush;
case 0x007: /* Mouse 4D and 2D */
case 0x09c:
case 0x094:
return QTabletEvent::FourDMouse;
case 0x017: /* Intuos3 2D Mouse */
case 0x806: /* Intuos4 Mouse */
case 0x096: /* Lens cursor */
case 0x097: /* Intuos3 Lens cursor */
case 0x006: /* Intuos4 Lens cursor */
return QTabletEvent::Puck;
case 0x885: /* Intuos3 Art Pen (Marker Pen) */
case 0x100804: /* Intuos4/5 13HD/24HD Art Pen */
case 0x10080c: /* Intuos4/5 13HD/24HD Art Pen Eraser */
return QTabletEvent::RotationStylus;
case 0:
return QTabletEvent::NoDevice;
}
return QTabletEvent::Stylus; // Safe default assumption if nonzero
}
#ifndef QT_NO_TABLETEVENT
bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData)
{
@ -713,9 +746,19 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData)
xi2ReportTabletEvent(*tabletData, xiEvent);
break;
case XI_PropertyEvent: {
// This is the wacom driver's way of reporting tool proximity.
// The evdev driver doesn't do it this way.
xXIPropertyEvent *ev = reinterpret_cast<xXIPropertyEvent *>(event);
if (ev->what == XIPropertyModified) {
if (ev->property == atom(QXcbAtom::WacomSerialIDs)) {
enum WacomSerialIndex {
_WACSER_USB_ID = 0,
_WACSER_LAST_TOOL_SERIAL,
_WACSER_LAST_TOOL_ID,
_WACSER_TOOL_SERIAL,
_WACSER_TOOL_ID,
_WACSER_COUNT
};
Atom propType;
int propFormat;
unsigned long numItems, bytesAfter;
@ -723,27 +766,44 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData)
if (XIGetProperty(xDisplay, tabletData->deviceId, ev->property, 0, 100,
0, AnyPropertyType, &propType, &propFormat,
&numItems, &bytesAfter, &data) == Success) {
if (propType == atom(QXcbAtom::INTEGER) && propFormat == 32) {
int *ptr = reinterpret_cast<int *>(data);
for (unsigned long i = 0; i < numItems; ++i)
tabletData->serialId |= qint64(ptr[i]) << (i * 32);
if (propType == atom(QXcbAtom::INTEGER) && propFormat == 32 && numItems == _WACSER_COUNT) {
quint32 *ptr = reinterpret_cast<quint32 *>(data);
quint32 tool = ptr[_WACSER_TOOL_ID];
// Workaround for http://sourceforge.net/p/linuxwacom/bugs/246/
// e.g. on Thinkpad Helix, tool ID will be 0 and serial will be 1
if (!tool && ptr[_WACSER_TOOL_SERIAL])
tool = ptr[_WACSER_TOOL_SERIAL];
// The property change event informs us which tool is in proximity or which one left proximity.
if (tool) {
tabletData->inProximity = true;
tabletData->tool = toolIdToTabletDevice(tool);
tabletData->serialId = qint64(ptr[_WACSER_USB_ID]) << 32 | qint64(ptr[_WACSER_TOOL_SERIAL]);
QWindowSystemInterface::handleTabletEnterProximityEvent(tabletData->tool,
tabletData->pointerType,
tabletData->serialId);
} else {
tabletData->inProximity = false;
tabletData->tool = toolIdToTabletDevice(ptr[_WACSER_LAST_TOOL_ID]);
// Workaround for http://sourceforge.net/p/linuxwacom/bugs/246/
// e.g. on Thinkpad Helix, tool ID will be 0 and serial will be 1
if (!tabletData->tool)
tabletData->tool = toolIdToTabletDevice(ptr[_WACSER_LAST_TOOL_SERIAL]);
tabletData->serialId = qint64(ptr[_WACSER_USB_ID]) << 32 | qint64(ptr[_WACSER_LAST_TOOL_SERIAL]);
QWindowSystemInterface::handleTabletLeaveProximityEvent(tabletData->tool,
tabletData->pointerType,
tabletData->serialId);
}
if (Q_UNLIKELY(debug_xinput)) {
// TODO maybe have a hash of tabletData->deviceId to device data so we can
// look up the tablet name here, and distinguish multiple tablets
qDebug("XI2 proximity change on tablet %d (USB %x): last tool: %x id %x current tool: %x id %x TabletDevice %d",
ev->deviceid, ptr[_WACSER_USB_ID], ptr[_WACSER_LAST_TOOL_SERIAL], ptr[_WACSER_LAST_TOOL_ID],
ptr[_WACSER_TOOL_SERIAL], ptr[_WACSER_TOOL_ID], tabletData->tool);
}
}
XFree(data);
}
// With recent-enough X drivers this property change event seems to come always
// when entering and leaving proximity. Due to the lack of other options hook up
// the enter/leave events to it.
if (tabletData->inProximity) {
tabletData->inProximity = false;
QWindowSystemInterface::handleTabletLeaveProximityEvent(QTabletEvent::Stylus,
tabletData->pointerType,
tabletData->serialId);
} else {
tabletData->inProximity = true;
QWindowSystemInterface::handleTabletEnterProximityEvent(QTabletEvent::Stylus,
tabletData->pointerType,
tabletData->serialId);
}
}
}
break;
@ -755,7 +815,7 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData)
return handled;
}
void QXcbConnection::xi2ReportTabletEvent(const TabletData &tabletData, void *event)
void QXcbConnection::xi2ReportTabletEvent(TabletData &tabletData, void *event)
{
xXIDeviceEvent *ev = reinterpret_cast<xXIDeviceEvent *>(event);
QXcbWindow *xcbWindow = platformWindowFromId(ev->event);
@ -765,45 +825,52 @@ void QXcbConnection::xi2ReportTabletEvent(const TabletData &tabletData, void *ev
const double scale = 65536.0;
QPointF local(ev->event_x / scale, ev->event_y / scale);
QPointF global(ev->root_x / scale, ev->root_y / scale);
double pressure = 0, rotation = 0;
double pressure = 0, rotation = 0, tangentialPressure = 0;
int xTilt = 0, yTilt = 0;
for (QHash<int, TabletData::ValuatorClassInfo>::const_iterator it = tabletData.valuatorInfo.constBegin(),
ite = tabletData.valuatorInfo.constEnd(); it != ite; ++it) {
for (QHash<int, TabletData::ValuatorClassInfo>::iterator it = tabletData.valuatorInfo.begin(),
ite = tabletData.valuatorInfo.end(); it != ite; ++it) {
int valuator = it.key();
const TabletData::ValuatorClassInfo &classInfo(it.value());
double value;
if (xi2GetValuatorValueIfSet(event, classInfo.number, &value)) {
double normalizedValue = (value - classInfo.minVal) / double(classInfo.maxVal - classInfo.minVal);
switch (valuator) {
case QXcbAtom::AbsPressure:
pressure = normalizedValue;
TabletData::ValuatorClassInfo &classInfo(it.value());
xi2GetValuatorValueIfSet(event, classInfo.number, &classInfo.curVal);
double normalizedValue = (classInfo.curVal - classInfo.minVal) / (classInfo.maxVal - classInfo.minVal);
switch (valuator) {
case QXcbAtom::AbsPressure:
pressure = normalizedValue;
break;
case QXcbAtom::AbsTiltX:
xTilt = classInfo.curVal;
break;
case QXcbAtom::AbsTiltY:
yTilt = classInfo.curVal;
break;
case QXcbAtom::AbsWheel:
switch (tabletData.tool) {
case QTabletEvent::Airbrush:
tangentialPressure = normalizedValue * 2.0 - 1.0; // Convert 0..1 range to -1..+1 range
break;
case QXcbAtom::AbsTiltX:
xTilt = value;
case QTabletEvent::RotationStylus:
rotation = normalizedValue * 360.0 - 180.0; // Convert 0..1 range to -180..+180 degrees
break;
case QXcbAtom::AbsTiltY:
yTilt = value;
break;
case QXcbAtom::AbsWheel:
rotation = value / 64.0;
break;
default:
default: // Other types of styli do not use this valuator
break;
}
break;
default:
break;
}
}
if (Q_UNLIKELY(debug_xinput))
qDebug("XI2 tablet event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f pressure %4.2lf tilt %d, %d rotation %6.2lf",
ev->type, ev->sequenceNumber, ev->detail,
qDebug("XI2 event on tablet %d with tool %d type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f pressure %4.2lf tilt %d, %d rotation %6.2lf",
ev->deviceid, tabletData.tool, ev->type, ev->sequenceNumber, ev->detail,
fixed1616ToReal(ev->event_x), fixed1616ToReal(ev->event_y),
fixed1616ToReal(ev->root_x), fixed1616ToReal(ev->root_y),
pressure, xTilt, yTilt, rotation);
QWindowSystemInterface::handleTabletEvent(window, tabletData.down, local, global,
QTabletEvent::Stylus, tabletData.pointerType,
pressure, xTilt, yTilt, 0,
tabletData.tool, tabletData.pointerType,
pressure, xTilt, yTilt, tangentialPressure,
rotation, 0, tabletData.serialId);
}
#endif // QT_NO_TABLETEVENT

View File

@ -26,7 +26,7 @@ qhp.QtXml.subprojects.classes.sortPages = true
tagfile = ../../../doc/qtxml/qtxml.tags
depends += qtcore qtnetwork qtdoc
depends += qtcore qtnetwork qtdoc qtwidgets
headerdirs += ..

View File

@ -710,11 +710,11 @@ void tst_QFont::defaultFamily_data()
QTest::addColumn<QFont::StyleHint>("styleHint");
QTest::addColumn<QStringList>("acceptableFamilies");
QTest::newRow("serif") << QFont::Serif << (QStringList() << "Times New Roman" << "Times" << getPlatformGenericFont("serif"));
QTest::newRow("monospace") << QFont::Monospace << (QStringList() << "Courier New" << "Monaco" << getPlatformGenericFont("monospace"));
QTest::newRow("cursive") << QFont::Cursive << (QStringList() << "Comic Sans MS" << "Apple Chancery" << getPlatformGenericFont("cursive"));
QTest::newRow("fantasy") << QFont::Fantasy << (QStringList() << "Impact" << "Zapfino" << getPlatformGenericFont("fantasy"));
QTest::newRow("sans-serif") << QFont::SansSerif << (QStringList() << "Arial" << "Lucida Grande" << getPlatformGenericFont("sans-serif"));
QTest::newRow("serif") << QFont::Serif << (QStringList() << "Times New Roman" << "Times" << "Droid Serif" << getPlatformGenericFont("serif"));
QTest::newRow("monospace") << QFont::Monospace << (QStringList() << "Courier New" << "Monaco" << "Droid Sans Mono" << getPlatformGenericFont("monospace"));
QTest::newRow("cursive") << QFont::Cursive << (QStringList() << "Comic Sans MS" << "Apple Chancery" << "Roboto" << "Droid Sans" << getPlatformGenericFont("cursive"));
QTest::newRow("fantasy") << QFont::Fantasy << (QStringList() << "Impact" << "Zapfino" << "Roboto" << "Droid Sans" << getPlatformGenericFont("fantasy"));
QTest::newRow("sans-serif") << QFont::SansSerif << (QStringList() << "Arial" << "Lucida Grande" << "Roboto" << "Droid Sans" << getPlatformGenericFont("sans-serif"));
}
void tst_QFont::defaultFamily()

View File

@ -9,3 +9,8 @@ wince* {
additionalFiles.path = .
DEPLOYMENT += additionalFiles
}
android {
RESOURCES += testdata.qrc
}

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>LED_REAL.TTF</file>
</qresource>
</RCC>

View File

@ -44,6 +44,8 @@
#include <qfontdatabase.h>
#include <qfontinfo.h>
#include <qfontmetrics.h>
#include <qtextlayout.h>
#include <private/qrawfont_p.h>
#include <qpa/qplatformfontdatabase.h>
class tst_QFontDatabase : public QObject
@ -77,6 +79,7 @@ private slots:
void addAppFont();
void aliases();
void fallbackFonts();
private:
const QString m_testFont;
@ -285,5 +288,26 @@ void tst_QFontDatabase::aliases()
QVERIFY(db.hasFamily(alias));
}
void tst_QFontDatabase::fallbackFonts()
{
QTextLayout layout;
QString s;
s.append(QChar(0x31));
s.append(QChar(0x05D0));
layout.setText(s);
layout.beginLayout();
layout.createLine();
layout.endLayout();
QList<QGlyphRun> runs = layout.glyphRuns(0, 1);
foreach (QGlyphRun run, runs) {
QRawFont rawFont = run.rawFont();
QVERIFY(rawFont.isValid());
QCOMPARE(run.glyphIndexes().size(), 1);
QVERIFY(run.glyphIndexes().at(0) != 0);
}
}
QTEST_MAIN(tst_QFontDatabase)
#include "tst_qfontdatabase.moc"