aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-09-21 10:40:27 +0200
committerUlf Hermann <ulf.hermann@qt.io>2020-10-02 13:21:09 +0200
commit45594322fe91eadcd9b2d7b1d76c1a6662bc1472 (patch)
treed14e743f40351ca7a660984616b2500aa83032f5 /src
parentd621027babff9a30d56ab6af871a465108c9eaba (diff)
Use factory functions and ctors for creating value types
As you can extend value types with QML_EXTENDED we may as well allow a factory function in the extended type. Furthermore, if the original type allows construction from QJSValue, we may just use that. In turn, we can get rid of the value type providers now. Change-Id: I9124ea47537eab6c33d7451080ab2fff942eaa7b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/qml/qqml.cpp2
-rw-r--r--src/qml/qml/qqml.h14
-rw-r--r--src/qml/qml/qqmlengine.cpp1
-rw-r--r--src/qml/qml/qqmlglobal.cpp67
-rw-r--r--src/qml/qml/qqmlglobal_p.h15
-rw-r--r--src/qml/qml/qqmlmetatype.cpp1
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp4
-rw-r--r--src/qml/qml/qqmlprivate.h53
-rw-r--r--src/qml/qml/qqmlpropertyvalidator.cpp2
-rw-r--r--src/qml/qml/qqmlstringconverters.cpp2
-rw-r--r--src/qml/qml/qqmltype.cpp8
-rw-r--r--src/qml/qml/qqmltype_p.h3
-rw-r--r--src/qml/qml/qqmltype_p_p.h1
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp8
-rw-r--r--src/quick/util/qquickglobal.cpp397
-rw-r--r--src/quick/util/qquickvaluetypes.cpp220
-rw-r--r--src/quick/util/qquickvaluetypes_p.h16
17 files changed, 337 insertions, 477 deletions
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index 102bf22df5..d26a09b081 100644
--- a/src/qml/qml/qqml.cpp
+++ b/src/qml/qml/qqml.cpp
@@ -321,6 +321,7 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
nullptr,
nullptr,
noCreateReason,
+ type.createValueType,
type.uri,
type.version,
nullptr,
@@ -493,6 +494,7 @@ namespace QQmlPrivate {
0,
nullptr,
nullptr,
+ nullptr,
uri,
QTypeRevision::fromMajorVersion(versionMajor),
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 758b0a51cf..be482c5277 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -172,6 +172,7 @@ int qmlRegisterAnonymousType(const char *uri, int versionMajor)
0,
nullptr, nullptr,
QString(),
+ QQmlPrivate::ValueType<T, void>::create,
uri, QTypeRevision::fromVersion(versionMajor, 0), nullptr,
QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
@@ -206,6 +207,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
nullptr,
nullptr,
reason,
+ QQmlPrivate::ValueType<T, void>::create,
uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName,
QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
@@ -237,6 +239,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
nullptr,
nullptr,
reason,
+ QQmlPrivate::ValueType<T, void>::create,
uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName,
QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
@@ -275,6 +278,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve
nullptr,
nullptr,
reason,
+ QQmlPrivate::ValueType<T, E>::create,
uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName,
QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
@@ -313,6 +317,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve
nullptr,
nullptr,
reason,
+ QQmlPrivate::ValueType<T, E>::create,
uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName,
QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
@@ -344,6 +349,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c
QQmlPrivate::QmlMetaType<T>::list(),
sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr,
QString(),
+ QQmlPrivate::ValueType<T, void>::create,
uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName,
QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
@@ -373,6 +379,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c
QQmlPrivate::QmlMetaType<T>::list(),
sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr,
QString(),
+ QQmlPrivate::ValueType<T, void>::create,
uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName,
QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
@@ -402,6 +409,7 @@ int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
QQmlPrivate::QmlMetaType<T>::list(),
sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr,
QString(),
+ QQmlPrivate::ValueType<T, void>::create,
uri, QTypeRevision::fromVersion(versionMajor, versionMinor), nullptr,
QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
@@ -433,6 +441,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor)
nullptr,
nullptr,
QString(),
+ QQmlPrivate::ValueType<T, E>::create,
uri, QTypeRevision::fromVersion(versionMajor, 0), nullptr,
QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
@@ -470,6 +479,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
QQmlPrivate::QmlMetaType<T>::list(),
sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr,
QString(),
+ QQmlPrivate::ValueType<T, E>::create,
uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName,
QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
@@ -518,6 +528,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
QQmlPrivate::QmlMetaType<T>::list(),
sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr,
QString(),
+ QQmlPrivate::ValueType<T, void>::create,
uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName,
QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
@@ -548,6 +559,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
QQmlPrivate::QmlMetaType<T>::list(),
sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr,
QString(),
+ QQmlPrivate::ValueType<T, void>::create,
uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName,
QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
@@ -585,6 +597,7 @@ int qmlRegisterCustomExtendedType(const char *uri, int versionMajor, int version
QQmlPrivate::QmlMetaType<T>::list(),
sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr,
QString(),
+ QQmlPrivate::ValueType<T, E>::create,
uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName,
QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
@@ -838,6 +851,7 @@ inline void qmlRegisterNamespaceAndRevisions(const QMetaObject *metaObject,
0,
nullptr,
nullptr,
+ nullptr,
uri,
QTypeRevision::fromMajorVersion(versionMajor),
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index f32a2901c6..3f871d5c6a 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -118,6 +118,7 @@ int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject,
nullptr,
nullptr,
reason,
+ nullptr,
uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &staticMetaObject,
diff --git a/src/qml/qml/qqmlglobal.cpp b/src/qml/qml/qqmlglobal.cpp
index 4d3c81037e..e3a5df382e 100644
--- a/src/qml/qml/qqmlglobal.cpp
+++ b/src/qml/qml/qqmlglobal.cpp
@@ -48,16 +48,6 @@
QT_BEGIN_NAMESPACE
-QQmlValueTypeProvider::QQmlValueTypeProvider()
- : next(nullptr)
-{
-}
-
-QQmlValueTypeProvider::~QQmlValueTypeProvider()
-{
- QQml_removeValueTypeProvider(this);
-}
-
bool QQmlValueTypeProvider::initValueType(int type, QVariant& dst)
{
const QMetaType metaType(type);
@@ -67,15 +57,16 @@ bool QQmlValueTypeProvider::initValueType(int type, QVariant& dst)
return true;
}
-bool QQmlValueTypeProvider::createValueType(int type, const QJSValue &s, QVariant *data)
+bool QQmlValueTypeProvider::createValueType(int type, const QJSValue &s, QVariant &data)
{
- Q_ASSERT(data);
-
- QQmlValueTypeProvider *p = this;
- do {
- if (p->create(type, s, data))
+ const QQmlType qmlType = QQmlMetaType::qmlType(type, QQmlMetaType::TypeIdCategory::MetaType);
+ if (auto valueTypeFunction = qmlType.createValueTypeFunction()) {
+ QVariant result = valueTypeFunction(s);
+ if (result.userType() == type) {
+ data = std::move(result);
return true;
- } while ((p = p->next));
+ }
+ }
return false;
}
@@ -109,49 +100,11 @@ bool QQmlValueTypeProvider::writeValueType(int type, const void *src, QVariant&
return true;
}
-bool QQmlValueTypeProvider::create(int, const QJSValue &, QVariant *) { return false; }
-
-struct ValueTypeProviderList {
- QQmlValueTypeProvider nullProvider;
- QQmlValueTypeProvider *head = &nullProvider;
-};
-
-Q_GLOBAL_STATIC(ValueTypeProviderList, valueTypeProviders)
-
-Q_QML_PRIVATE_EXPORT void QQml_addValueTypeProvider(QQmlValueTypeProvider *newProvider)
-{
- if (ValueTypeProviderList *providers = valueTypeProviders()) {
- newProvider->next = providers->head;
- providers->head = newProvider;
- }
-}
-
-Q_QML_PRIVATE_EXPORT void QQml_removeValueTypeProvider(QQmlValueTypeProvider *oldProvider)
-{
- if (ValueTypeProviderList *providers = valueTypeProviders()) {
- QQmlValueTypeProvider *prev = providers->head;
- if (prev == oldProvider) {
- providers->head = oldProvider->next;
- return;
- }
-
- // singly-linked list removal
- for (; prev; prev = prev->next) {
- if (prev->next != oldProvider)
- continue; // this is not the provider you're looking for
- prev->next = oldProvider->next;
- return;
- }
-
- qWarning("QQml_removeValueTypeProvider: was asked to remove provider %p but it was not found", oldProvider);
- }
-}
+Q_GLOBAL_STATIC(QQmlValueTypeProvider, valueTypeProvider)
Q_AUTOTEST_EXPORT QQmlValueTypeProvider *QQml_valueTypeProvider()
{
- if (ValueTypeProviderList *providers = valueTypeProviders())
- return providers->head;
- return nullptr;
+ return valueTypeProvider();
}
QQmlColorProvider::~QQmlColorProvider() {}
diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h
index 98ef809f0a..365bb1aa15 100644
--- a/src/qml/qml/qqmlglobal_p.h
+++ b/src/qml/qml/qqmlglobal_p.h
@@ -219,28 +219,15 @@ inline void QQml_setParent_noEvent(QObject *object, QObject *parent)
class Q_QML_PRIVATE_EXPORT QQmlValueTypeProvider
{
public:
- QQmlValueTypeProvider();
- virtual ~QQmlValueTypeProvider();
-
bool initValueType(int, QVariant&);
- bool createValueType(int, const QJSValue &, QVariant *);
+ bool createValueType(int, const QJSValue &, QVariant &);
bool equalValueType(int, const void *, const QVariant&);
bool readValueType(const QVariant&, void *, int);
bool writeValueType(int, const void *, QVariant&);
-
-private:
- virtual bool create(int, const QJSValue &params, QVariant *);
-
- friend Q_QML_PRIVATE_EXPORT void QQml_addValueTypeProvider(QQmlValueTypeProvider *);
- friend Q_QML_PRIVATE_EXPORT void QQml_removeValueTypeProvider(QQmlValueTypeProvider *);
-
- QQmlValueTypeProvider *next;
};
-Q_QML_PRIVATE_EXPORT void QQml_addValueTypeProvider(QQmlValueTypeProvider *);
Q_AUTOTEST_EXPORT QQmlValueTypeProvider *QQml_valueTypeProvider();
-
class Q_QML_PRIVATE_EXPORT QQmlColorProvider
{
public:
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 6eaf2063b5..b89d19b199 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -170,6 +170,7 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el
d->extraData.cd->userdata = type.userdata;
d->extraData.cd->newFunc = type.create;
d->extraData.cd->noCreationReason = type.noCreationReason;
+ d->extraData.cd->createValueTypeFunc = type.createValueType;
d->baseMetaObject = type.metaObject;
d->extraData.cd->attachedPropertiesFunc = type.attachedPropertiesFunction;
d->extraData.cd->attachedPropertiesType = type.attachedPropertiesMetaObject;
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index dc25aa9f0a..45c9400934 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -485,7 +485,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
case QMetaType::QColor: {
QVariant data;
if (QQml_valueTypeProvider()->createValueType(
- QMetaType::QColor, compilationUnit->bindingValueAsString(binding), &data)) {
+ QMetaType::QColor, compilationUnit->bindingValueAsString(binding), data)) {
property->writeProperty(_qobject, data.data(), propertyWriteFlags);
}
}
@@ -568,7 +568,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
case QMetaType::QQuaternion: {
QVariant result;
bool ok = QQml_valueTypeProvider()->createValueType(
- propertyType, compilationUnit->bindingValueAsString(binding), &result);
+ propertyType, compilationUnit->bindingValueAsString(binding), result);
assertOrNull(ok);
Q_UNUSED(ok);
property->writeProperty(_qobject, result.data(), propertyWriteFlags);
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index 00d277a9f7..6639ecbd26 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -58,6 +58,7 @@
#include <QtQml/qqmlparserstatus.h>
#include <QtQml/qqmllist.h>
#include <QtQml/qqmlpropertyvaluesource.h>
+#include <QtQml/qjsvalue.h>
#include <QtCore/qglobal.h>
#include <QtCore/qvariant.h>
@@ -109,7 +110,6 @@ public:
};
-class QJSValue;
class QJSEngine;
class QQmlEngine;
class QQmlCustomParser;
@@ -163,6 +163,7 @@ namespace QQmlPrivate
using CreateIntoFunction = void (*)(void *, void *);
using CreateSingletonFunction = QObject *(*)(QQmlEngine *, QJSEngine *);
using CreateParentFunction = QObject *(*)(QObject *);
+ using CreateValueTypeFunction = QVariant (*)(const QJSValue &);
template<typename T, bool Constructible = isConstructible<T>()>
struct Constructors;
@@ -211,6 +212,51 @@ namespace QQmlPrivate
static const QMetaObject *staticMetaObject() { return &T::staticMetaObject; }
};
+ template<typename F, typename Result = void>
+ struct ValueTypeFactory
+ {
+ static constexpr const Result (*create)(const QJSValue &) = nullptr;
+ };
+
+ template<typename F>
+ struct ValueTypeFactory<F, std::void_t<decltype(F::create(QJSValue()))>>
+ {
+ static decltype(F::create(QJSValue())) create(const QJSValue &params)
+ {
+ return F::create(params);
+ }
+ };
+
+ template<typename T, typename F,
+ bool HasCtor = std::is_constructible_v<T, QJSValue>,
+ bool HasFactory = std::is_constructible_v<
+ QVariant, decltype(ValueTypeFactory<F>::create(QJSValue()))>>
+ struct ValueType;
+
+ template<typename T, typename F>
+ struct ValueType<T, F, false, false>
+ {
+ static constexpr const CreateValueTypeFunction create = nullptr;
+ };
+
+ template<typename T, typename F, bool HasCtor>
+ struct ValueType<T, F, HasCtor, true>
+ {
+ static QVariant create(const QJSValue &params)
+ {
+ return F::create(params);
+ }
+ };
+
+ template<typename T, typename F>
+ struct ValueType<T, F, true, false>
+ {
+ static QVariant create(const QJSValue &params)
+ {
+ return QVariant::fromValue(T(params));
+ }
+ };
+
template<class From, class To, int N>
struct StaticCastSelectorClass
{
@@ -348,6 +394,8 @@ namespace QQmlPrivate
void *userdata;
QString noCreationReason;
+ QVariant (*createValueType)(const QJSValue &);
+
const char *uri;
QTypeRevision version;
const char *elementName;
@@ -378,6 +426,8 @@ namespace QQmlPrivate
void (*create)(void *, void *);
void *userdata;
+ QVariant (*createValueType)(const QJSValue &);
+
const char *uri;
QTypeRevision version;
@@ -676,6 +726,7 @@ namespace QQmlPrivate
QmlMetaType<T>::list(),
int(sizeof(T)),
Constructors<T>::createInto, nullptr,
+ ValueType<T, E>::create,
uri,
QTypeRevision::fromMajorVersion(versionMajor),
diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp
index 5bb3abd396..9ad5d3d42f 100644
--- a/src/qml/qml/qqmlpropertyvalidator.cpp
+++ b/src/qml/qml/qqmlpropertyvalidator.cpp
@@ -567,7 +567,7 @@ QQmlError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *prope
QVariant result;
if (!QQml_valueTypeProvider()->createValueType(
property->propType(),
- compilationUnit->bindingValueAsString(binding), &result)) {
+ compilationUnit->bindingValueAsString(binding), result)) {
return warnOrError(tr("Invalid property assignment: %1 expected")
.arg(typeName()));
}
diff --git a/src/qml/qml/qqmlstringconverters.cpp b/src/qml/qml/qqmlstringconverters.cpp
index c7c111a052..9c2e715a6a 100644
--- a/src/qml/qml/qqmlstringconverters.cpp
+++ b/src/qml/qml/qqmlstringconverters.cpp
@@ -77,7 +77,7 @@ QVariant QQmlStringConverters::variantFromString(const QString &s, int preferred
return QVariant::fromValue(rectFFromString(s, ok).toRect());
default: {
QVariant ret;
- bool success = QQml_valueTypeProvider()->createValueType(preferredType, QJSValue(s), &ret);
+ bool success = QQml_valueTypeProvider()->createValueType(preferredType, QJSValue(s), ret);
if (ok)
*ok = success;
return ret;
diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp
index bea69166c6..2c74d04ffc 100644
--- a/src/qml/qml/qqmltype.cpp
+++ b/src/qml/qml/qqmltype.cpp
@@ -63,6 +63,7 @@ QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type)
extraData.cd = new QQmlCppTypeData;
extraData.cd->allocationSize = 0;
extraData.cd->newFunc = nullptr;
+ extraData.cd->createValueTypeFunc = nullptr;
extraData.cd->parserStatusCast = -1;
extraData.cd->extFunc = nullptr;
extraData.cd->extMetaObject = nullptr;
@@ -516,6 +517,13 @@ QQmlCustomParser *QQmlType::customParser() const
return d->extraData.cd->customParser;
}
+QQmlType::CreateValueTypeFunc QQmlType::createValueTypeFunction() const
+{
+ if (!d || d->regType != CppType)
+ return nullptr;
+ return d->extraData.cd->createValueTypeFunc;
+}
+
QQmlType::CreateFunc QQmlType::createFunction() const
{
if (!d || d->regType != CppType)
diff --git a/src/qml/qml/qqmltype_p.h b/src/qml/qml/qqmltype_p.h
index 025a1e5555..0655583e1e 100644
--- a/src/qml/qml/qqmltype_p.h
+++ b/src/qml/qml/qqmltype_p.h
@@ -104,6 +104,9 @@ public:
bool availableInVersion(QTypeRevision version) const;
bool availableInVersion(const QHashedStringRef &module, QTypeRevision version) const;
+ typedef QVariant (*CreateValueTypeFunc)(const QJSValue &);
+ CreateValueTypeFunc createValueTypeFunction() const;
+
QObject *create() const;
void create(QObject **, void **, size_t) const;
diff --git a/src/qml/qml/qqmltype_p_p.h b/src/qml/qml/qqmltype_p_p.h
index cdd46aee7c..426b9ced37 100644
--- a/src/qml/qml/qqmltype_p_p.h
+++ b/src/qml/qml/qqmltype_p_p.h
@@ -116,6 +116,7 @@ public:
void (*newFunc)(void *, void *);
void *userdata = nullptr;
QString noCreationReason;
+ QVariant (*createValueTypeFunc)(const QJSValue &);
int parserStatusCast;
QObject *(*extFunc)(QObject *);
const QMetaObject *extMetaObject;
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 12e54f0895..3b6c448e49 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -463,7 +463,7 @@ ReturnedValue QtObject::method_font(const FunctionObject *b, const Value *, cons
QVariant v;
if (!QQml_valueTypeProvider()->createValueType(
QMetaType::QFont, QJSValuePrivate::fromReturnedValue(argv[0].asReturnedValue()),
- &v)) {
+ v)) {
THROW_GENERIC_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified");
}
return scope.engine->fromVariant(v);
@@ -483,7 +483,7 @@ static ReturnedValue createValueType(const FunctionObject *b, const Value *argv,
params.setProperty(i, QJSValuePrivate::fromReturnedValue(argv[i].asReturnedValue()));
QVariant variant;
- QQml_valueTypeProvider()->createValueType(type, params, &variant);
+ QQml_valueTypeProvider()->createValueType(type, params, variant);
return scope.engine->fromVariant(variant);
}
@@ -554,7 +554,7 @@ ReturnedValue QtObject::method_matrix4x4(const FunctionObject *b, const Value *,
if (argc == 0) {
QVariant variant;
- QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, QJSValue(), &variant);
+ QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, QJSValue(), variant);
return scope.engine->fromVariant(variant);
}
@@ -562,7 +562,7 @@ ReturnedValue QtObject::method_matrix4x4(const FunctionObject *b, const Value *,
QVariant v;
if (!QQml_valueTypeProvider()->createValueType(
QMetaType::QMatrix4x4,
- QJSValuePrivate::fromReturnedValue(argv[0].asReturnedValue()), &v)) {
+ QJSValuePrivate::fromReturnedValue(argv[0].asReturnedValue()), v)) {
THROW_GENERIC_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array");
}
return scope.engine->fromVariant(v);
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index c12137efe3..ab6cb24bfb 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -285,395 +285,6 @@ public:
}
};
-
-// Note: The functions in this class provide handling only for the types
-// that the QML engine will currently actually call them for, so many
-// appear incompletely implemented. For some functions, the implementation
-// would be obvious, but for others (particularly create)
-// the exact semantics are unknown. For this reason unused functionality
-// has been omitted.
-
-class QQuickValueTypeProvider : public QQmlValueTypeProvider
-{
-public:
-
-#if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
- #define ASSERT_VALID_SIZE(size, min) Q_UNUSED(size);
-#else
- #define ASSERT_VALID_SIZE(size, min) Q_ASSERT(size >= min)
-#endif
-
- static QVector2D vector2DFromString(const QString &s, bool *ok)
- {
- if (s.count(QLatin1Char(',')) == 1) {
- int index = s.indexOf(QLatin1Char(','));
-
- bool xGood, yGood;
- float xCoord = QStringView{s}.left(index).toFloat(&xGood);
- float yCoord = QStringView{s}.mid(index + 1).toFloat(&yGood);
-
- if (xGood && yGood) {
- if (ok) *ok = true;
- return QVector2D(xCoord, yCoord);
- }
- }
-
- if (ok) *ok = false;
- return QVector2D();
- }
-
- static QVector3D vector3DFromString(const QString &s, bool *ok)
- {
- if (s.count(QLatin1Char(',')) == 2) {
- int index = s.indexOf(QLatin1Char(','));
- int index2 = s.indexOf(QLatin1Char(','), index+1);
-
- bool xGood, yGood, zGood;
- float xCoord = QStringView{s}.left(index).toFloat(&xGood);
- float yCoord = QStringView{s}.mid(index + 1, index2 - index - 1).toFloat(&yGood);
- float zCoord = QStringView{s}.mid(index2 + 1).toFloat(&zGood);
-
- if (xGood && yGood && zGood) {
- if (ok) *ok = true;
- return QVector3D(xCoord, yCoord, zCoord);
- }
- }
-
- if (ok) *ok = false;
- return QVector3D();
- }
-
- static QVector4D vector4DFromString(const QString &s, bool *ok)
- {
- if (s.count(QLatin1Char(',')) == 3) {
- int index = s.indexOf(QLatin1Char(','));
- int index2 = s.indexOf(QLatin1Char(','), index+1);
- int index3 = s.indexOf(QLatin1Char(','), index2+1);
-
- bool xGood, yGood, zGood, wGood;
- float xCoord = QStringView{s}.left(index).toFloat(&xGood);
- float yCoord = QStringView{s}.mid(index + 1, index2 - index - 1).toFloat(&yGood);
- float zCoord = QStringView{s}.mid(index2 + 1, index3 - index2 - 1).toFloat(&zGood);
- float wCoord = QStringView{s}.mid(index3 + 1).toFloat(&wGood);
-
- if (xGood && yGood && zGood && wGood) {
- if (ok) *ok = true;
- return QVector4D(xCoord, yCoord, zCoord, wCoord);
- }
- }
-
- if (ok) *ok = false;
- return QVector4D();
- }
-
- static QQuaternion quaternionFromString(const QString &s, bool *ok)
- {
- if (s.count(QLatin1Char(',')) == 3) {
- int index = s.indexOf(QLatin1Char(','));
- int index2 = s.indexOf(QLatin1Char(','), index+1);
- int index3 = s.indexOf(QLatin1Char(','), index2+1);
-
- bool sGood, xGood, yGood, zGood;
- qreal sCoord = QStringView{s}.left(index).toDouble(&sGood);
- qreal xCoord = QStringView{s}.mid(index+1, index2-index-1).toDouble(&xGood);
- qreal yCoord = QStringView{s}.mid(index2+1, index3-index2-1).toDouble(&yGood);
- qreal zCoord = QStringView{s}.mid(index3+1).toDouble(&zGood);
-
- if (sGood && xGood && yGood && zGood) {
- if (ok) *ok = true;
- return QQuaternion(sCoord, xCoord, yCoord, zCoord);
- }
- }
-
- if (ok) *ok = false;
- return QQuaternion();
- }
-
- static QMatrix4x4 matrix4x4FromString(const QString &s, bool *ok)
- {
- if (s.count(QLatin1Char(',')) == 15) {
- float matValues[16];
- bool vOK = true;
- QStringView mutableStr(s);
- for (int i = 0; vOK && i < 16; ++i) {
- int cidx = mutableStr.indexOf(QLatin1Char(','));
- matValues[i] = mutableStr.left(cidx).toDouble(&vOK);
- mutableStr = mutableStr.mid(cidx + 1);
- }
-
- if (vOK) {
- if (ok) *ok = true;
- return QMatrix4x4(matValues);
- }
- }
-
- if (ok) *ok = false;
- return QMatrix4x4();
- }
-
- static QColorSpace colorSpaceFromObject(const QJSValue &object, bool *ok)
- {
- if (ok)
- *ok = false;
-
- QColorSpace retn;
- if (!object.isObject())
- return retn;
-
- const QJSValue vName = object.property(QStringLiteral("namedColorSpace"));
- if (vName.isNumber()) {
- if (ok)
- *ok = true;
- return QColorSpace((QColorSpace::NamedColorSpace)vName.toInt());
- }
-
- const QJSValue vPri = object.property(QStringLiteral("primaries"));
- const QJSValue vTra = object.property(QStringLiteral("transferFunction"));
- if (!vPri.isNumber() || !vTra.isNumber())
- return retn;
-
- QColorSpace::Primaries pri = static_cast<QColorSpace::Primaries>(vPri.toInt());
- QColorSpace::TransferFunction tra = static_cast<QColorSpace::TransferFunction>(vTra.toInt());
- float gamma = 0.0f;
- if (tra == QColorSpace::TransferFunction::Gamma) {
- const QJSValue vGam = object.property(QStringLiteral("gamma"));
- if (!vGam.isNumber())
- return retn;
- gamma = vGam.toNumber();
- }
-
- if (ok)
- *ok = true;
- return QColorSpace(pri, tra, gamma);
- }
-
- static QFont fontFromObject(const QJSValue &object, bool *ok)
- {
- if (ok)
- *ok = false;
- QFont retn;
-
- if (!object.isObject()) {
- if (ok)
- *ok = false;
- return retn;
- }
-
- const QJSValue vbold = object.property(QStringLiteral("bold"));
- const QJSValue vcap = object.property(QStringLiteral("capitalization"));
- const QJSValue vfam = object.property(QStringLiteral("family"));
- const QJSValue vstyle = object.property(QStringLiteral("styleName"));
- const QJSValue vital = object.property(QStringLiteral("italic"));
- const QJSValue vlspac = object.property(QStringLiteral("letterSpacing"));
- const QJSValue vpixsz = object.property(QStringLiteral("pixelSize"));
- const QJSValue vpntsz = object.property(QStringLiteral("pointSize"));
- const QJSValue vstrk = object.property(QStringLiteral("strikeout"));
- const QJSValue vundl = object.property(QStringLiteral("underline"));
- const QJSValue vweight = object.property(QStringLiteral("weight"));
- const QJSValue vwspac = object.property(QStringLiteral("wordSpacing"));
- const QJSValue vhint = object.property(QStringLiteral("hintingPreference"));
- const QJSValue vkerning = object.property(QStringLiteral("kerning"));
- const QJSValue vshaping = object.property(QStringLiteral("preferShaping"));
-
- // pull out the values, set ok to true if at least one valid field is given.
- if (vbold.isBool()) {
- retn.setBold(vbold.toBool());
- if (ok) *ok = true;
- }
- if (vcap.isNumber()) {
- retn.setCapitalization(static_cast<QFont::Capitalization>(vcap.toInt()));
- if (ok) *ok = true;
- }
- if (vfam.isString()) {
- retn.setFamily(vfam.toString());
- if (ok) *ok = true;
- }
- if (vstyle.isString()) {
- retn.setStyleName(vstyle.toString());
- if (ok) *ok = true;
- }
- if (vital.isBool()) {
- retn.setItalic(vital.toBool());
- if (ok) *ok = true;
- }
- if (vlspac.isNumber()) {
- retn.setLetterSpacing(QFont::AbsoluteSpacing, vlspac.toNumber());
- if (ok) *ok = true;
- }
- if (vpixsz.isNumber()) {
- retn.setPixelSize(vpixsz.toInt());
- if (ok) *ok = true;
- }
- if (vpntsz.isNumber()) {
- retn.setPointSize(vpntsz.toNumber());
- if (ok) *ok = true;
- }
- if (vstrk.isBool()) {
- retn.setStrikeOut(vstrk.toBool());
- if (ok) *ok = true;
- }
- if (vundl.isBool()) {
- retn.setUnderline(vundl.toBool());
- if (ok) *ok = true;
- }
- if (vweight.isNumber()) {
- retn.setWeight(QFont::Weight(vweight.toInt()));
- if (ok) *ok = true;
- }
- if (vwspac.isNumber()) {
- retn.setWordSpacing(vwspac.toNumber());
- if (ok) *ok = true;
- }
- if (vhint.isNumber()) {
- retn.setHintingPreference(static_cast<QFont::HintingPreference>(vhint.toInt()));
- if (ok) *ok = true;
- }
- if (vkerning.isBool()) {
- retn.setKerning(vkerning.toBool());
- if (ok) *ok = true;
- }
- if (vshaping.isBool()) {
- bool enable = vshaping.toBool();
- if (enable)
- retn.setStyleStrategy(static_cast<QFont::StyleStrategy>(retn.styleStrategy() & ~QFont::PreferNoShaping));
- else
- retn.setStyleStrategy(static_cast<QFont::StyleStrategy>(retn.styleStrategy() | QFont::PreferNoShaping));
- }
-
- return retn;
- }
-
- bool create(int type, const QJSValue &params, QVariant *v) override
- {
- switch (type) {
- case QMetaType::QColor:
- if (params.isString()) {
- *v = QVariant(QColor(params.toString()));
- return true;
- }
- break;
- case QMetaType::QColorSpace: {
- bool ok = false;
- auto val = colorSpaceFromObject(params, &ok);
- if (ok) {
- *v = QVariant::fromValue(val);
- return true;
- }
- break;
- }
- case QMetaType::QFont: {
- bool ok = false;
- auto val = fontFromObject(params, &ok);
- if (ok) {
- *v = QVariant::fromValue(val);
- return true;
- }
- break;
- }
- case QMetaType::QVector2D:
- if (params.isArray()) {
- *v = QVariant(QVector2D(params.property(0).toNumber(),
- params.property(1).toNumber()));
- return true;
- } else if (params.isString()) {
- bool ok = false;
- auto vector = vector2DFromString(params.toString(), &ok);
- if (ok) {
- *v = QVariant(vector);
- return true;
- }
- }
- break;
- case QMetaType::QVector3D:
- if (params.isArray()) {
- *v = QVariant(QVector3D(params.property(0).toNumber(),
- params.property(1).toNumber(),
- params.property(2).toNumber()));
- return true;
- } else if (params.isString()) {
- bool ok = false;
- auto vector = vector3DFromString(params.toString(), &ok);
- if (ok) {
- *v = QVariant(vector);
- return true;
- }
- }
- break;
- case QMetaType::QVector4D:
- if (params.isArray()) {
- *v = QVariant(QVector4D(params.property(0).toNumber(),
- params.property(1).toNumber(),
- params.property(2).toNumber(),
- params.property(3).toNumber()));
- return true;
- } else if (params.isString()) {
- bool ok = false;
- auto vector = vector4DFromString(params.toString(), &ok);
- if (ok) {
- *v = QVariant(vector);
- return true;
- }
- }
- break;
- case QMetaType::QQuaternion:
- if (params.isArray()) {
- *v = QVariant(QQuaternion(params.property(0).toNumber(),
- params.property(1).toNumber(),
- params.property(2).toNumber(),
- params.property(3).toNumber()));
- return true;
- } else if (params.isString()) {
- bool ok = false;
- auto vector = quaternionFromString(params.toString(), &ok);
- if (ok) {
- *v = QVariant(vector);
- return true;
- }
- }
- break;
- case QMetaType::QMatrix4x4:
- if (params.isNull() || params.isUndefined()) {
- QMatrix4x4 m;
- *v = QVariant(m);
- return true;
- } else if (params.isArray()
- && params.property(QStringLiteral("length")).toInt() == 16) {
- *v = QVariant(QMatrix4x4(params.property(0).toNumber(),
- params.property(1).toNumber(),
- params.property(2).toNumber(),
- params.property(3).toNumber(),
- params.property(4).toNumber(),
- params.property(5).toNumber(),
- params.property(6).toNumber(),
- params.property(7).toNumber(),
- params.property(8).toNumber(),
- params.property(9).toNumber(),
- params.property(10).toNumber(),
- params.property(11).toNumber(),
- params.property(12).toNumber(),
- params.property(13).toNumber(),
- params.property(14).toNumber(),
- params.property(15).toNumber()));
- return true;
- } else if (params.isString()) {
- bool ok = false;
- auto vector = matrix4x4FromString(params.toString(), &ok);
- if (ok) {
- *v = QVariant(vector);
- return true;
- }
- }
- break;
- default: break;
- }
-
- return false;
- }
-
-#undef ASSERT_VALID_SIZE
-};
-
-
class QQuickGuiProvider : public QQmlGuiProvider
{
public:
@@ -720,13 +331,6 @@ public:
}
};
-
-static QQuickValueTypeProvider *getValueTypeProvider()
-{
- static QQuickValueTypeProvider valueTypeProvider;
- return &valueTypeProvider;
-}
-
static QQuickColorProvider *getColorProvider()
{
static QQuickColorProvider colorProvider;
@@ -744,7 +348,6 @@ void QQuick_initializeModule()
// This is used by QQuickPath, and on macOS it fails to automatically register.
qRegisterMetaType<QVector<QVector<QPointF>>>();
- QQml_addValueTypeProvider(getValueTypeProvider());
QQml_setColorProvider(getColorProvider());
QQml_setGuiProvider(getGuiProvider());
diff --git a/src/quick/util/qquickvaluetypes.cpp b/src/quick/util/qquickvaluetypes.cpp
index 5bbfdbcbea..cbd641fecf 100644
--- a/src/quick/util/qquickvaluetypes.cpp
+++ b/src/quick/util/qquickvaluetypes.cpp
@@ -46,6 +46,11 @@
QT_BEGIN_NAMESPACE
+QVariant QQuickColorValueType::create(const QJSValue &params)
+{
+ return params.isString() ? QColor(params.toString()) : QVariant();
+}
+
QString QQuickColorValueType::toString() const
{
return v.name(v.alpha() != 255 ? QColor::HexArgb : QColor::HexRgb);
@@ -188,6 +193,53 @@ void QQuickColorValueType::setHslLightness(qreal hslLightness)
v.setHslF(hue, saturation, hslLightness, alpha);
}
+template<typename T, int NumParams>
+QVariant createValueTypeFromNumberString(const QString &s)
+{
+ Q_STATIC_ASSERT_X(NumParams == 2 || NumParams == 3 || NumParams == 4 || NumParams == 16,
+ "Unsupported number of params; add an additional case below if necessary.");
+
+ if (s.count(u',') != NumParams - 1)
+ return QVariant();
+
+ QVarLengthArray<float, NumParams> parameters;
+ bool ok = true;
+ for (qsizetype prev = 0, next = s.indexOf(u','), length = s.length(); ok && prev < length;) {
+ parameters.append(s.mid(prev, next - prev).toFloat(&ok));
+ prev = next + 1;
+ next = (parameters.length() == NumParams - 1) ? length : s.indexOf(u',', prev);
+ }
+
+ if (!ok)
+ return QVariant();
+
+ if constexpr (NumParams == 2) {
+ return T(parameters[0], parameters[1]);
+ } else if constexpr (NumParams == 3) {
+ return T(parameters[0], parameters[1], parameters[2]);
+ } else if constexpr (NumParams == 4) {
+ return T(parameters[0], parameters[1], parameters[2], parameters[3]);
+ } else if constexpr (NumParams == 16) {
+ return T(parameters[0], parameters[1], parameters[2], parameters[3],
+ parameters[4], parameters[5], parameters[6], parameters[7],
+ parameters[8], parameters[9], parameters[10], parameters[11],
+ parameters[12], parameters[13], parameters[14], parameters[15]);
+ } else {
+ Q_UNREACHABLE();
+ }
+
+ return QVariant();
+}
+
+QVariant QQuickVector2DValueType::create(const QJSValue &params)
+{
+ if (params.isString())
+ return createValueTypeFromNumberString<QVector2D, 2>(params.toString());
+ if (params.isArray())
+ return QVector2D(params.property(0).toNumber(), params.property(1).toNumber());
+ return QVariant();
+}
+
QString QQuickVector2DValueType::toString() const
{
return QString(QLatin1String("QVector2D(%1, %2)")).arg(v.x()).arg(v.y());
@@ -273,6 +325,18 @@ bool QQuickVector2DValueType::fuzzyEquals(const QVector2D &vec) const
return qFuzzyCompare(v, vec);
}
+QVariant QQuickVector3DValueType::create(const QJSValue &params)
+{
+ if (params.isString())
+ return createValueTypeFromNumberString<QVector3D, 3>(params.toString());
+
+ if (params.isArray()) {
+ return QVector3D(params.property(0).toNumber(), params.property(1).toNumber(),
+ params.property(2).toNumber());
+ }
+ return QVariant();
+}
+
QString QQuickVector3DValueType::toString() const
{
return QString(QLatin1String("QVector3D(%1, %2, %3)")).arg(v.x()).arg(v.y()).arg(v.z());
@@ -380,6 +444,19 @@ bool QQuickVector3DValueType::fuzzyEquals(const QVector3D &vec) const
return qFuzzyCompare(v, vec);
}
+QVariant QQuickVector4DValueType::create(const QJSValue &params)
+{
+ if (params.isString())
+ return createValueTypeFromNumberString<QVector4D, 4>(params.toString());
+
+ if (params.isArray()) {
+ return QVector4D(params.property(0).toNumber(), params.property(1).toNumber(),
+ params.property(2).toNumber(), params.property(3).toNumber());
+ }
+
+ return QVariant();
+}
+
QString QQuickVector4DValueType::toString() const
{
return QString(QLatin1String("QVector4D(%1, %2, %3, %4)")).arg(v.x()).arg(v.y()).arg(v.z()).arg(v.w());
@@ -494,6 +571,19 @@ bool QQuickVector4DValueType::fuzzyEquals(const QVector4D &vec) const
return qFuzzyCompare(v, vec);
}
+QVariant QQuickQuaternionValueType::create(const QJSValue &params)
+{
+ if (params.isString())
+ return createValueTypeFromNumberString<QQuaternion, 4>(params.toString());
+
+ if (params.isArray()) {
+ return QQuaternion(params.property(0).toNumber(), params.property(1).toNumber(),
+ params.property(2).toNumber(), params.property(3).toNumber());
+ }
+
+ return QVariant();
+}
+
QString QQuickQuaternionValueType::toString() const
{
return QString(QLatin1String("QQuaternion(%1, %2, %3, %4)")).arg(v.scalar()).arg(v.x()).arg(v.y()).arg(v.z());
@@ -539,6 +629,36 @@ void QQuickQuaternionValueType::setZ(qreal z)
v.setZ(z);
}
+QVariant QQuickMatrix4x4ValueType::create(const QJSValue &params)
+{
+ if (params.isNull() || params.isUndefined())
+ return QMatrix4x4();
+
+ if (params.isString())
+ return createValueTypeFromNumberString<QMatrix4x4, 16>(params.toString());
+
+ if (params.isArray() && params.property(QStringLiteral("length")).toInt() == 16) {
+ return QMatrix4x4(params.property(0).toNumber(),
+ params.property(1).toNumber(),
+ params.property(2).toNumber(),
+ params.property(3).toNumber(),
+ params.property(4).toNumber(),
+ params.property(5).toNumber(),
+ params.property(6).toNumber(),
+ params.property(7).toNumber(),
+ params.property(8).toNumber(),
+ params.property(9).toNumber(),
+ params.property(10).toNumber(),
+ params.property(11).toNumber(),
+ params.property(12).toNumber(),
+ params.property(13).toNumber(),
+ params.property(14).toNumber(),
+ params.property(15).toNumber());
+ }
+
+ return QVariant();
+}
+
QMatrix4x4 QQuickMatrix4x4ValueType::times(const QMatrix4x4 &m) const
{
return v * m;
@@ -612,6 +732,78 @@ bool QQuickMatrix4x4ValueType::fuzzyEquals(const QMatrix4x4 &m) const
return qFuzzyCompare(v, m);
}
+template<typename T>
+void setFontProperty(QFont &font, void (QFont::*setter)(T value), QString name,
+ const QJSValue &params, bool *ok)
+{
+ const QJSValue value = params.property(name);
+
+ if constexpr (std::is_same_v<T, bool>) {
+ if (value.isBool()) {
+ (font.*setter)(value.toBool());
+ *ok = true;
+ }
+ } else if constexpr (std::is_same_v<
+ typename std::remove_cv<typename std::remove_reference<T>::type>::type,
+ QString>) {
+ if (value.isString()) {
+ (font.*setter)(value.toString());
+ *ok = true;
+ }
+ } else if constexpr (std::is_integral_v<T> || std::is_enum_v<T>) {
+ if (value.isNumber()) {
+ (font.*setter)(T(value.toInt()));
+ *ok = true;
+ }
+ } else if constexpr (std::is_floating_point_v<T>) {
+ if (value.isNumber()) {
+ (font.*setter)(value.toNumber());
+ *ok = true;
+ }
+ }
+}
+
+QVariant QQuickFontValueType::create(const QJSValue &params)
+{
+ if (!params.isObject())
+ return QVariant();
+
+ bool ok = false;
+ QFont ret;
+
+ setFontProperty(ret, &QFont::setBold, QStringLiteral("bold"), params, &ok);
+ setFontProperty(ret, &QFont::setCapitalization, QStringLiteral("capitalization"), params, &ok);
+ setFontProperty(ret, &QFont::setFamily, QStringLiteral("family"), params, &ok);
+ setFontProperty(ret, &QFont::setItalic, QStringLiteral("italic"), params, &ok);
+ setFontProperty(ret, &QFont::setPixelSize, QStringLiteral("pixelSize"), params, &ok);
+ setFontProperty(ret, &QFont::setPointSize, QStringLiteral("pointSize"), params, &ok);
+ setFontProperty(ret, &QFont::setStrikeOut, QStringLiteral("strikeout"), params, &ok);
+ setFontProperty(ret, &QFont::setUnderline, QStringLiteral("underline"), params, &ok);
+ setFontProperty(ret, &QFont::setWeight, QStringLiteral("weight"), params, &ok);
+ setFontProperty(ret, &QFont::setWordSpacing, QStringLiteral("wordSpacing"), params, &ok);
+ setFontProperty(ret, &QFont::setHintingPreference, QStringLiteral("hintingPreference"), params, &ok);
+ setFontProperty(ret, &QFont::setKerning, QStringLiteral("kerning"), params, &ok);
+
+ const QJSValue vlspac = params.property(QStringLiteral("letterSpacing"));
+ if (vlspac.isNumber()) {
+ ret.setLetterSpacing(QFont::AbsoluteSpacing, vlspac.toNumber());
+ ok = true;
+ }
+
+ const QJSValue vshaping = params.property(QStringLiteral("preferShaping"));
+ if (vshaping.isBool()) {
+ const bool enable = vshaping.toBool();
+ const QFont::StyleStrategy strategy = ret.styleStrategy();
+ if (enable)
+ ret.setStyleStrategy(QFont::StyleStrategy(strategy & ~QFont::PreferNoShaping));
+ else
+ ret.setStyleStrategy(QFont::StyleStrategy(strategy | QFont::PreferNoShaping));
+ ok = true;
+ }
+
+ return ok ? ret : QVariant();
+}
+
QString QQuickFontValueType::toString() const
{
return QString(QLatin1String("QFont(%1)")).arg(v.toString());
@@ -797,6 +989,34 @@ void QQuickFontValueType::setPreferShaping(bool enable)
v.setStyleStrategy(static_cast<QFont::StyleStrategy>(v.styleStrategy() | QFont::PreferNoShaping));
}
+QVariant QQuickColorSpaceValueType::create(const QJSValue &params)
+{
+ if (!params.isObject())
+ return QVariant();
+
+
+ const QJSValue vName = params.property(QStringLiteral("namedColorSpace"));
+ if (vName.isNumber())
+ return QColorSpace((QColorSpace::NamedColorSpace)vName.toInt());
+
+ const QJSValue vPri = params.property(QStringLiteral("primaries"));
+ const QJSValue vTra = params.property(QStringLiteral("transferFunction"));
+ if (!vPri.isNumber() || !vTra.isNumber())
+ return QVariant();
+
+ QColorSpace::Primaries pri = static_cast<QColorSpace::Primaries>(vPri.toInt());
+ QColorSpace::TransferFunction tra = static_cast<QColorSpace::TransferFunction>(vTra.toInt());
+ float gamma = 0.0f;
+ if (tra == QColorSpace::TransferFunction::Gamma) {
+ const QJSValue vGam = params.property(QStringLiteral("gamma"));
+ if (!vGam.isNumber())
+ return QVariant();
+ gamma = vGam.toNumber();
+ }
+
+ return QColorSpace(pri, tra, gamma);
+}
+
QQuickColorSpaceEnums::NamedColorSpace QQuickColorSpaceValueType::namedColorSpace() const noexcept
{
if (const auto *p = QColorSpacePrivate::get(v))
diff --git a/src/quick/util/qquickvaluetypes_p.h b/src/quick/util/qquickvaluetypes_p.h
index ed91d5d6be..f9b66586e0 100644
--- a/src/quick/util/qquickvaluetypes_p.h
+++ b/src/quick/util/qquickvaluetypes_p.h
@@ -87,6 +87,8 @@ class QQuickColorValueType
QML_EXTENDED(QQuickColorValueType)
public:
+ static QVariant create(const QJSValue &params);
+
Q_INVOKABLE QString toString() const;
Q_INVOKABLE QVariant alpha(qreal value) const;
@@ -129,6 +131,8 @@ class QQuickVector2DValueType
QML_EXTENDED(QQuickVector2DValueType)
public:
+ static QVariant create(const QJSValue &params);
+
Q_INVOKABLE QString toString() const;
qreal x() const;
@@ -162,6 +166,8 @@ class QQuickVector3DValueType
QML_EXTENDED(QQuickVector3DValueType)
public:
+ static QVariant create(const QJSValue &params);
+
Q_INVOKABLE QString toString() const;
qreal x() const;
@@ -200,6 +206,8 @@ class QQuickVector4DValueType
QML_EXTENDED(QQuickVector4DValueType)
public:
+ static QVariant create(const QJSValue &params);
+
Q_INVOKABLE QString toString() const;
qreal x() const;
@@ -239,6 +247,8 @@ class QQuickQuaternionValueType
QML_EXTENDED(QQuickQuaternionValueType)
public:
+ static QVariant create(const QJSValue &params);
+
Q_INVOKABLE QString toString() const;
qreal scalar() const;
@@ -277,6 +287,8 @@ class QQuickMatrix4x4ValueType
QML_EXTENDED(QQuickMatrix4x4ValueType)
public:
+ static QVariant create(const QJSValue &params);
+
qreal m11() const { return v(0, 0); }
qreal m12() const { return v(0, 1); }
qreal m13() const { return v(0, 2); }
@@ -397,6 +409,8 @@ class QQuickFontValueType
QML_EXTENDED(QQuickFontValueType)
public:
+ static QVariant create(const QJSValue &value);
+
Q_INVOKABLE QString toString() const;
QString family() const;
@@ -499,6 +513,8 @@ class QQuickColorSpaceValueType
QML_EXTENDED(QQuickColorSpaceValueType)
public:
+ static QVariant create(const QJSValue &params);
+
QQuickColorSpaceEnums::NamedColorSpace namedColorSpace() const noexcept;
void setNamedColorSpace(QQuickColorSpaceEnums::NamedColorSpace namedColorSpace);
QQuickColorSpaceEnums::Primaries primaries() const noexcept;