Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickvaluetypes.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include <private/qquickvaluetypes_p.h>
6
7#include <qtquickglobal.h>
8#include <private/qqmlvaluetype_p.h>
9#include <private/qqmlstringconverters_p.h>
10#include <private/qcolorspace_p.h>
11#include <private/qfont_p.h>
12
13QT_BEGIN_NAMESPACE
14
15QQuickColorValueType::QQuickColorValueType(const QString &string)
16 : QColor(QColor::fromString(string))
17{
18}
19
20QVariant QQuickColorValueType::create(const QJSValue &params)
21{
22 return params.isString() ? QColor::fromString(params.toString()) : QVariant();
23}
24
25QString QQuickColorValueType::toString() const
26{
27 return QColor::name(QColor::alpha() != 255 ? QColor::HexArgb : QColor::HexRgb);
28}
29
30int QQuickColorValueType::rgba() const
31{
32 return QColor::rgba();
33}
34
35QColor QQuickColorValueType::lighter(qreal factor) const
36{
37 if (std::isnan(factor)) {
38 qWarning("NaN given as argument to color.lighter()");
39 return QColor();
40 }
41
42 return QColor::lighter(int(qRound(factor*100.)));
43}
44
45QColor QQuickColorValueType::darker(qreal factor) const
46{
47 if (std::isnan(factor)) {
48 qWarning("NaN given as argument to color.darker()");
49 return QColor();
50 }
51
52 return QColor::darker(int(qRound(factor*100.)));
53}
54
55QColor QQuickColorValueType::alpha(qreal value) const
56{
57 QColor color = *this;
58 color.setAlphaF(value);
59 return color;
60}
61
62QColor QQuickColorValueType::tint(const QColor &tintColor) const
63{
64 int tintAlpha = tintColor.alpha();
65 if (tintAlpha == 0xFF)
66 return tintColor;
67 else if (tintAlpha == 0x00)
68 return *this;
69
70 // tint the base color and return the final color
71 const QColor baseColor = QColor::toRgb();
72 const qreal a = tintColor.alphaF();
73 const qreal inv_a = 1.0 - a;
74
75 const qreal r = tintColor.redF() * a + baseColor.redF() * inv_a;
76 const qreal g = tintColor.greenF() * a + baseColor.greenF() * inv_a;
77 const qreal b = tintColor.blueF() * a + baseColor.blueF() * inv_a;
78
79 return QColor::fromRgbF(r, g, b, a + inv_a * baseColor.alphaF());
80}
81
82qreal QQuickColorValueType::r() const
83{
84 return QColor::redF();
85}
86
87qreal QQuickColorValueType::g() const
88{
89 return QColor::greenF();
90}
91
92qreal QQuickColorValueType::b() const
93{
94 return QColor::blueF();
95}
96
97qreal QQuickColorValueType::a() const
98{
99 return QColor::alphaF();
100}
101
102qreal QQuickColorValueType::hsvHue() const
103{
104 return QColor::hsvHueF();
105}
106
107qreal QQuickColorValueType::hsvSaturation() const
108{
109 return QColor::hsvSaturationF();
110}
111
112qreal QQuickColorValueType::hsvValue() const
113{
114 return QColor::valueF();
115}
116
117qreal QQuickColorValueType::hslHue() const
118{
119 return QColor::hslHueF();
120}
121
122qreal QQuickColorValueType::hslSaturation() const
123{
124 return QColor::hslSaturationF();
125}
126
127qreal QQuickColorValueType::hslLightness() const
128{
129 return QColor::lightnessF();
130}
131
132bool QQuickColorValueType::isValid() const
133{
134 return QColor::isValid();
135}
136
137void QQuickColorValueType::setR(qreal r)
138{
139 QColor::setRedF(r);
140}
141
142void QQuickColorValueType::setG(qreal g)
143{
144 QColor::setGreenF(g);
145}
146
147void QQuickColorValueType::setB(qreal b)
148{
149 QColor::setBlueF(b);
150}
151
152void QQuickColorValueType::setA(qreal a)
153{
154 QColor::setAlphaF(a);
155}
156
157void QQuickColorValueType::setHsvHue(qreal hsvHue)
158{
159 float hue, saturation, value, alpha;
160 QColor::getHsvF(&hue, &saturation, &value, &alpha);
161 QColor::setHsvF(hsvHue, saturation, value, alpha);
162}
163
164void QQuickColorValueType::setHsvSaturation(qreal hsvSaturation)
165{
166 float hue, saturation, value, alpha;
167 QColor::getHsvF(&hue, &saturation, &value, &alpha);
168 QColor::setHsvF(hue, hsvSaturation, value, alpha);
169}
170
171void QQuickColorValueType::setHsvValue(qreal hsvValue)
172{
173 float hue, saturation, value, alpha;
174 QColor::getHsvF(&hue, &saturation, &value, &alpha);
175 QColor::setHsvF(hue, saturation, hsvValue, alpha);
176}
177
178void QQuickColorValueType::setHslHue(qreal hslHue)
179{
180 float hue, saturation, lightness, alpha;
181 QColor::getHslF(&hue, &saturation, &lightness, &alpha);
182 QColor::setHslF(hslHue, saturation, lightness, alpha);
183}
184
185void QQuickColorValueType::setHslSaturation(qreal hslSaturation)
186{
187 float hue, saturation, lightness, alpha;
188 QColor::getHslF(&hue, &saturation, &lightness, &alpha);
189 QColor::setHslF(hue, hslSaturation, lightness, alpha);
190}
191
192void QQuickColorValueType::setHslLightness(qreal hslLightness)
193{
194 float hue, saturation, lightness, alpha;
195 QColor::getHslF(&hue, &saturation, &lightness, &alpha);
196 QColor::setHslF(hue, saturation, hslLightness, alpha);
197}
198
199QVariant QQuickVector2DValueType::create(const QJSValue &params)
200{
201 if (params.isString())
202 return QQmlStringConverters::valueTypeFromNumberString<QVector2D, 2, u','>(params.toString());
203 if (params.isArray())
204 return QVector2D(params.property(0).toNumber(), params.property(1).toNumber());
205 return QVariant();
206}
207
208QString QQuickVector2DValueType::toString() const
209{
210 return QString::fromLatin1("QVector2D(%1, %2)").arg(QVector2D::x()).arg(QVector2D::y());
211}
212
213qreal QQuickVector2DValueType::x() const
214{
215 return QVector2D::x();
216}
217
218qreal QQuickVector2DValueType::y() const
219{
220 return QVector2D::y();
221}
222
223void QQuickVector2DValueType::setX(qreal x)
224{
225 QVector2D::setX(x);
226}
227
228void QQuickVector2DValueType::setY(qreal y)
229{
230 QVector2D::setY(y);
231}
232
233qreal QQuickVector2DValueType::dotProduct(const QVector2D &vec) const
234{
235 return QVector2D::dotProduct(*this, vec);
236}
237
238QVector2D QQuickVector2DValueType::times(const QVector2D &vec) const
239{
240 return *this * vec;
241}
242
243QVector2D QQuickVector2DValueType::times(qreal scalar) const
244{
245 return *this * scalar;
246}
247
248QVector2D QQuickVector2DValueType::plus(const QVector2D &vec) const
249{
250 return *this + vec;
251}
252
253QVector2D QQuickVector2DValueType::minus(const QVector2D &vec) const
254{
255 return *this - vec;
256}
257
258QVector2D QQuickVector2DValueType::normalized() const
259{
260 return QVector2D::normalized();
261}
262
263qreal QQuickVector2DValueType::length() const
264{
265 return QVector2D::length();
266}
267
268QVector3D QQuickVector2DValueType::toVector3d() const
269{
270 return QVector2D::toVector3D();
271}
272
273QVector4D QQuickVector2DValueType::toVector4d() const
274{
275 return QVector2D::toVector4D();
276}
277
278bool QQuickVector2DValueType::fuzzyEquals(const QVector2D &vec, qreal epsilon) const
279{
280 qreal absEps = qAbs(epsilon);
281 if (qAbs(QVector2D::x() - vec.x()) > absEps)
282 return false;
283 if (qAbs(QVector2D::y() - vec.y()) > absEps)
284 return false;
285 return true;
286}
287
288bool QQuickVector2DValueType::fuzzyEquals(const QVector2D &vec) const
289{
290 return qFuzzyCompare(*this, vec);
291}
292
293QVariant QQuickVector3DValueType::create(const QJSValue &params)
294{
295 if (params.isString()) {
296 return QQmlStringConverters::valueTypeFromNumberString<QVector3D, 3, u',', u','>(
297 params.toString());
298 }
299
300 if (params.isArray()) {
301 return QVector3D(params.property(0).toNumber(), params.property(1).toNumber(),
302 params.property(2).toNumber());
303 }
304 return QVariant();
305}
306
307QString QQuickVector3DValueType::toString() const
308{
309 return QString::fromLatin1("QVector3D(%1, %2, %3)")
310 .arg(QVector3D::x()).arg(QVector3D::y()).arg(QVector3D::z());
311}
312
313qreal QQuickVector3DValueType::x() const
314{
315 return QVector3D::x();
316}
317
318qreal QQuickVector3DValueType::y() const
319{
320 return QVector3D::y();
321}
322
323qreal QQuickVector3DValueType::z() const
324{
325 return QVector3D::z();
326}
327
328void QQuickVector3DValueType::setX(qreal x)
329{
330 QVector3D::setX(x);
331}
332
333void QQuickVector3DValueType::setY(qreal y)
334{
335 QVector3D::setY(y);
336}
337
338void QQuickVector3DValueType::setZ(qreal z)
339{
340 QVector3D::setZ(z);
341}
342
343QVector3D QQuickVector3DValueType::crossProduct(const QVector3D &vec) const
344{
345 return QVector3D::crossProduct(*this, vec);
346}
347
348qreal QQuickVector3DValueType::dotProduct(const QVector3D &vec) const
349{
350 return QVector3D::dotProduct(*this, vec);
351}
352
353QVector3D QQuickVector3DValueType::times(const QMatrix4x4 &m) const
354{
355 return (QVector4D(*this, 1) * m).toVector3DAffine();
356}
357
358QVector3D QQuickVector3DValueType::times(const QVector3D &vec) const
359{
360 return *this * vec;
361}
362
363QVector3D QQuickVector3DValueType::times(qreal scalar) const
364{
365 return *this * scalar;
366}
367
368QVector3D QQuickVector3DValueType::plus(const QVector3D &vec) const
369{
370 return *this + vec;
371}
372
373QVector3D QQuickVector3DValueType::minus(const QVector3D &vec) const
374{
375 return *this - vec;
376}
377
378QVector3D QQuickVector3DValueType::normalized() const
379{
380 return QVector3D::normalized();
381}
382
383qreal QQuickVector3DValueType::length() const
384{
385 return QVector3D::length();
386}
387
388QVector2D QQuickVector3DValueType::toVector2d() const
389{
390 return QVector3D::toVector2D();
391}
392
393QVector4D QQuickVector3DValueType::toVector4d() const
394{
395 return QVector3D::toVector4D();
396}
397
398bool QQuickVector3DValueType::fuzzyEquals(const QVector3D &vec, qreal epsilon) const
399{
400 qreal absEps = qAbs(epsilon);
401 if (qAbs(QVector3D::x() - vec.x()) > absEps)
402 return false;
403 if (qAbs(QVector3D::y() - vec.y()) > absEps)
404 return false;
405 if (qAbs(QVector3D::z() - vec.z()) > absEps)
406 return false;
407 return true;
408}
409
410bool QQuickVector3DValueType::fuzzyEquals(const QVector3D &vec) const
411{
412 return qFuzzyCompare(*this, vec);
413}
414
415QVariant QQuickVector4DValueType::create(const QJSValue &params)
416{
417 if (params.isString()) {
418 return QQmlStringConverters::valueTypeFromNumberString<QVector4D, 4, u',', u',', u','>(
419 params.toString());
420 }
421
422 if (params.isArray()) {
423 return QVector4D(params.property(0).toNumber(), params.property(1).toNumber(),
424 params.property(2).toNumber(), params.property(3).toNumber());
425 }
426
427 return QVariant();
428}
429
430QString QQuickVector4DValueType::toString() const
431{
432 return QString::fromLatin1("QVector4D(%1, %2, %3, %4)")
433 .arg(QVector4D::x()).arg(QVector4D::y()).arg(QVector4D::z()).arg(QVector4D::w());
434}
435
436qreal QQuickVector4DValueType::x() const
437{
438 return QVector4D::x();
439}
440
441qreal QQuickVector4DValueType::y() const
442{
443 return QVector4D::y();
444}
445
446qreal QQuickVector4DValueType::z() const
447{
448 return QVector4D::z();
449}
450
451qreal QQuickVector4DValueType::w() const
452{
453 return QVector4D::w();
454}
455
456void QQuickVector4DValueType::setX(qreal x)
457{
458 QVector4D::setX(x);
459}
460
461void QQuickVector4DValueType::setY(qreal y)
462{
463 QVector4D::setY(y);
464}
465
466void QQuickVector4DValueType::setZ(qreal z)
467{
468 QVector4D::setZ(z);
469}
470
471void QQuickVector4DValueType::setW(qreal w)
472{
473 QVector4D::setW(w);
474}
475
476qreal QQuickVector4DValueType::dotProduct(const QVector4D &vec) const
477{
478 return QVector4D::dotProduct(*this, vec);
479}
480
481QVector4D QQuickVector4DValueType::times(const QVector4D &vec) const
482{
483 return *this * vec;
484}
485
486QVector4D QQuickVector4DValueType::times(const QMatrix4x4 &m) const
487{
488 return *this * m;
489}
490
491QVector4D QQuickVector4DValueType::times(qreal scalar) const
492{
493 return *this * scalar;
494}
495
496QVector4D QQuickVector4DValueType::plus(const QVector4D &vec) const
497{
498 return *this + vec;
499}
500
501QVector4D QQuickVector4DValueType::minus(const QVector4D &vec) const
502{
503 return *this - vec;
504}
505
506QVector4D QQuickVector4DValueType::normalized() const
507{
508 return QVector4D::normalized();
509}
510
511qreal QQuickVector4DValueType::length() const
512{
513 return QVector4D::length();
514}
515
516QVector2D QQuickVector4DValueType::toVector2d() const
517{
518 return QVector4D::toVector2D();
519}
520
521QVector3D QQuickVector4DValueType::toVector3d() const
522{
523 return QVector4D::toVector3D();
524}
525
526bool QQuickVector4DValueType::fuzzyEquals(const QVector4D &vec, qreal epsilon) const
527{
528 qreal absEps = qAbs(epsilon);
529 if (qAbs(QVector4D::x() - vec.x()) > absEps)
530 return false;
531 if (qAbs(QVector4D::y() - vec.y()) > absEps)
532 return false;
533 if (qAbs(QVector4D::z() - vec.z()) > absEps)
534 return false;
535 if (qAbs(QVector4D::w() - vec.w()) > absEps)
536 return false;
537 return true;
538}
539
540bool QQuickVector4DValueType::fuzzyEquals(const QVector4D &vec) const
541{
542 return qFuzzyCompare(*this, vec);
543}
544
545QVariant QQuickQuaternionValueType::create(const QJSValue &params)
546{
547 if (params.isString()) {
548 return QQmlStringConverters::valueTypeFromNumberString<QQuaternion, 4, u',', u',', u','>(
549 params.toString());
550 }
551
552 if (params.isArray()) {
553 return QQuaternion(params.property(0).toNumber(), params.property(1).toNumber(),
554 params.property(2).toNumber(), params.property(3).toNumber());
555 }
556
557 return QVariant();
558}
559
560QString QQuickQuaternionValueType::toString() const
561{
562 return QString::fromLatin1("QQuaternion(%1, %2, %3, %4)")
563 .arg(QQuaternion::scalar())
564 .arg(QQuaternion::x())
565 .arg(QQuaternion::y())
566 .arg(QQuaternion::z());
567}
568
569qreal QQuickQuaternionValueType::scalar() const
570{
571 return QQuaternion::scalar();
572}
573
574qreal QQuickQuaternionValueType::x() const
575{
576 return QQuaternion::x();
577}
578
579qreal QQuickQuaternionValueType::y() const
580{
581 return QQuaternion::y();
582}
583
584qreal QQuickQuaternionValueType::z() const
585{
586 return QQuaternion::z();
587}
588
589void QQuickQuaternionValueType::setScalar(qreal scalar)
590{
591 QQuaternion::setScalar(scalar);
592}
593
594void QQuickQuaternionValueType::setX(qreal x)
595{
596 QQuaternion::setX(x);
597}
598
599void QQuickQuaternionValueType::setY(qreal y)
600{
601 QQuaternion::setY(y);
602}
603
604void QQuickQuaternionValueType::setZ(qreal z)
605{
606 QQuaternion::setZ(z);
607}
608
609qreal QQuickQuaternionValueType::dotProduct(const QQuaternion &q) const
610{
611 return QQuaternion::dotProduct(*this, q);
612}
613
614QQuaternion QQuickQuaternionValueType::times(const QQuaternion &q) const
615{
616 return *this * q;
617}
618
619QVector3D QQuickQuaternionValueType::times(const QVector3D &vec) const
620{
621 return *this * vec;
622}
623
624QQuaternion QQuickQuaternionValueType::times(qreal factor) const
625{
626 return *this * factor;
627}
628
629QQuaternion QQuickQuaternionValueType::plus(const QQuaternion &q) const
630{
631 return *this + q;
632}
633
634QQuaternion QQuickQuaternionValueType::minus(const QQuaternion &q) const
635{
636 return *this - q;
637}
638
639QQuaternion QQuickQuaternionValueType::normalized() const
640{
641 return QQuaternion::normalized();
642}
643
644QQuaternion QQuickQuaternionValueType::inverted() const
645{
646 return QQuaternion::inverted();
647}
648
649QQuaternion QQuickQuaternionValueType::conjugated() const
650{
651 return QQuaternion::conjugated();
652}
653
654qreal QQuickQuaternionValueType::length() const
655{
656 return QQuaternion::length();
657}
658
659QVector3D QQuickQuaternionValueType::toEulerAngles() const
660{
661 return QQuaternion::toEulerAngles();
662}
663
664QVector4D QQuickQuaternionValueType::toVector4d() const
665{
666 return QQuaternion::toVector4D();
667}
668
669bool QQuickQuaternionValueType::fuzzyEquals(const QQuaternion &q, qreal epsilon) const
670{
671 qreal absEps = qAbs(epsilon);
672 if (qAbs(QQuaternion::scalar() - q.scalar()) > absEps)
673 return false;
674 if (qAbs(QQuaternion::x() - q.x()) > absEps)
675 return false;
676 if (qAbs(QQuaternion::y() - q.y()) > absEps)
677 return false;
678 if (qAbs(QQuaternion::z() - q.z()) > absEps)
679 return false;
680 return true;
681}
682
683bool QQuickQuaternionValueType::fuzzyEquals(const QQuaternion &q) const
684{
685 return qFuzzyCompare(*this, q);
686}
687
688QVariant QQuickMatrix4x4ValueType::create(const QJSValue &params)
689{
690 if (params.isNull() || params.isUndefined())
691 return QMatrix4x4();
692
693 if (params.isString()) {
694 return QQmlStringConverters::valueTypeFromNumberString<QMatrix4x4, 16, u',', u',', u',',
695 u',', u',', u',', u',', u',', u',',
696 u',', u',', u',', u',', u',', u','>(
697 params.toString());
698 }
699
700 if (params.isArray() && params.property(QStringLiteral("length")).toInt() == 16) {
701 return QMatrix4x4(params.property(0).toNumber(),
702 params.property(1).toNumber(),
703 params.property(2).toNumber(),
704 params.property(3).toNumber(),
705 params.property(4).toNumber(),
706 params.property(5).toNumber(),
707 params.property(6).toNumber(),
708 params.property(7).toNumber(),
709 params.property(8).toNumber(),
710 params.property(9).toNumber(),
711 params.property(10).toNumber(),
712 params.property(11).toNumber(),
713 params.property(12).toNumber(),
714 params.property(13).toNumber(),
715 params.property(14).toNumber(),
716 params.property(15).toNumber());
717 }
718
719 return QVariant();
720}
721
722QMatrix4x4 QQuickMatrix4x4ValueType::times(const QMatrix4x4 &m) const
723{
724 return *this * m;
725}
726
727QVector4D QQuickMatrix4x4ValueType::times(const QVector4D &vec) const
728{
729 return *this * vec;
730}
731
732QVector3D QQuickMatrix4x4ValueType::times(const QVector3D &vec) const
733{
734 return QMatrix4x4::map(vec);
735}
736
737QMatrix4x4 QQuickMatrix4x4ValueType::times(qreal factor) const
738{
739 return *this * factor;
740}
741
742QMatrix4x4 QQuickMatrix4x4ValueType::plus(const QMatrix4x4 &m) const
743{
744 return *this + m;
745}
746
747QMatrix4x4 QQuickMatrix4x4ValueType::minus(const QMatrix4x4 &m) const
748{
749 return *this - m;
750}
751
752QVector4D QQuickMatrix4x4ValueType::row(int n) const
753{
754 return QMatrix4x4::row(n);
755}
756
757QVector4D QQuickMatrix4x4ValueType::column(int m) const
758{
759 return QMatrix4x4::column(m);
760}
761
762qreal QQuickMatrix4x4ValueType::determinant() const
763{
764 return QMatrix4x4::determinant();
765}
766
767QMatrix4x4 QQuickMatrix4x4ValueType::inverted() const
768{
769 return QMatrix4x4::inverted();
770}
771
772QMatrix4x4 QQuickMatrix4x4ValueType::transposed() const
773{
774 return QMatrix4x4::transposed();
775}
776
777QPointF QQuickMatrix4x4ValueType::map(const QPointF p) const
778{
779 return QMatrix4x4::map(p);
780}
781
782QRectF QQuickMatrix4x4ValueType::mapRect(const QRectF r) const
783{
784 return QMatrix4x4::mapRect(r);
785}
786
787bool QQuickMatrix4x4ValueType::fuzzyEquals(const QMatrix4x4 &m, qreal epsilon) const
788{
789 qreal absEps = qAbs(epsilon);
790 for (int i = 0; i < 4; ++i) {
791 for (int j = 0; j < 4; ++j) {
792 if (qAbs((*this)(i,j) - m(i,j)) > absEps) {
793 return false;
794 }
795 }
796 }
797 return true;
798}
799
800bool QQuickMatrix4x4ValueType::fuzzyEquals(const QMatrix4x4 &m) const
801{
802 return qFuzzyCompare(*this, m);
803}
804
805/*!
806 \qmltype PlanarTransform
807 \inqmlmodule QtQuick
808 \since 6.8
809
810 \brief Provides utility functions for matrix4x4 when used for 2D transforms.
811
812 The \c PlanarTransform is a global object with utility functions.
813
814 It is not instantiable; to use it, call the members of the global \c PlanarTransform object
815 directly. For example:
816
817 \qml
818 Item {
819 transform: Matrix4x4 { matrix: PlanarTransform.fromAffineMatrix(1, 0, 0.36, 1, -36, 0) }
820 }
821 \endqml
822*/
823
824QQuickPlanarTransform::QQuickPlanarTransform(QObject *parent)
825 : QObject(parent)
826{
827}
828
829/*!
830 \qmlmethod matrix4x4 PlanarTransform::identity()
831
832 Returns a matrix4x4 for the identity transform.
833
834 This is equivalent to \l Qt::matrix4x4().
835*/
836
837QMatrix4x4 QQuickPlanarTransform::identity()
838{
839 return QMatrix4x4();
840}
841
842/*!
843 \qmlmethod matrix4x4 PlanarTransform::fromAffineMatrix(real scaleX, real shearY,
844 real shearX, real scaleY,
845 real translateX, real translateY)
846
847 Returns a matrix4x4 for an affine (non-projecting) 2D transform with the specified values.
848
849 This method and its argument order correspond to SVG's \c matrix() function and the
850 six-argument QTransform constructor. The result is this 4x4 matrix:
851
852 \table
853 \row \li \a scaleX \li \a shearX \li 0 \li \a translateX
854 \row \li \a shearY \li \a scaleY \li 0 \li \a translateY
855 \row \li 0 \li 0 \li 1 \li 0
856 \row \li 0 \li 0 \li 0 \li 1
857 \endtable
858*/
859
860QMatrix4x4 QQuickPlanarTransform::fromAffineMatrix(float scaleX, float shearY,
861 float shearX, float scaleY,
862 float translateX, float translateY)
863{
864 return QMatrix4x4(scaleX, shearX, 0, translateX,
865 shearY, scaleY, 0, translateY,
866 0, 0, 1, 0,
867 0, 0, 0, 1);
868}
869
870/*!
871 \qmlmethod matrix4x4 PlanarTransform::fromTranslate(real translateX, real translateY)
872
873 Returns a matrix4x4 for a 2D transform that translates by \a translateX horizontally and
874 \a translateY vertically.
875*/
876QMatrix4x4 QQuickPlanarTransform::fromTranslate(float translateX, float translateY)
877{
878 QMatrix4x4 xf;
879 xf.translate(translateX, translateY);
880 return xf;
881}
882
883/*!
884 \qmlmethod matrix4x4 PlanarTransform::fromScale(real scaleX, real scaleY, real originX, real originY)
885
886 Returns a matrix4x4 for a 2D transform that scales by \a scaleX horizontally and \a scaleY
887 vertically, centered at the point (\a originX, \a originY).
888
889 \a originX and \a originY are optional and default to (0, 0).
890*/
891QMatrix4x4 QQuickPlanarTransform::fromScale(float scaleX, float scaleY, float originX, float originY)
892{
893 QMatrix4x4 xf;
894 xf.translate(originX, originY);
895 xf.scale(scaleX, scaleY);
896 xf.translate(-originX, -originY);
897 return xf;
898}
899
900/*!
901 \qmlmethod matrix4x4 PlanarTransform::fromRotate(real angle, real originX, real originY)
902
903 Returns a matrix4x4 for a 2D transform that rotates by \a angle degrees around the point (\a
904 originX, \a originY).
905
906 \a originX and \a originY are optional and default to (0, 0).
907*/
908QMatrix4x4 QQuickPlanarTransform::fromRotate(float angle, float originX, float originY)
909{
910 QMatrix4x4 xf;
911 xf.translate(originX, originY);
912 xf.rotate(angle, 0, 0, 1);
913 xf.translate(-originX, -originY);
914 return xf;
915}
916
917/*!
918 \qmlmethod matrix4x4 PlanarTransform::fromShear(float shearX, float shearY, float originX, float originY)
919
920 Returns a matrix4x4 for a 2D transform that shears by \a shearX horizontally and \a shearY
921 vertically, centered at the point (\a originX, \a originY).
922
923 \a originX and \a originY are optional and default to (0, 0).
924*/
925QMatrix4x4 QQuickPlanarTransform::fromShear(float shearX, float shearY, float originX, float originY)
926{
927 QMatrix4x4 xf;
928 xf.translate(originX, originY);
929 xf *= QMatrix4x4(1, shearX, 0, 0, shearY, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
930 xf.translate(-originX, -originY);
931 return xf;
932}
933
934template<typename T>
935void setFontProperty(QFont &font, void (QFont::*setter)(T value), QString name,
936 const QJSValue &params, bool *ok)
937{
938 const QJSValue value = params.property(name);
939
940 if constexpr (std::is_same_v<T, bool>) {
941 if (value.isBool()) {
942 (font.*setter)(value.toBool());
943 *ok = true;
944 }
945 } else if constexpr (std::is_same_v<
946 typename std::remove_cv<typename std::remove_reference<T>::type>::type,
947 QString>) {
948 if (value.isString()) {
949 (font.*setter)(value.toString());
950 *ok = true;
951 }
952 } else if constexpr (std::is_integral_v<T> || std::is_enum_v<T>) {
953 if (value.isNumber()) {
954 (font.*setter)(T(value.toInt()));
955 *ok = true;
956 }
957 } else if constexpr (std::is_floating_point_v<T>) {
958 if (value.isNumber()) {
959 (font.*setter)(value.toNumber());
960 *ok = true;
961 }
962 }
963}
964
965QVariant QQuickFontValueType::create(const QJSValue &params)
966{
967 if (!params.isObject())
968 return QVariant();
969
970 bool ok = false;
971 QFont ret;
972
973 setFontProperty(ret, &QFont::setBold, QStringLiteral("bold"), params, &ok);
974 setFontProperty(ret, &QFont::setCapitalization, QStringLiteral("capitalization"), params, &ok);
975 setFontProperty(ret, &QFont::setFamily, QStringLiteral("family"), params, &ok);
976 setFontProperty(ret, &QFont::setItalic, QStringLiteral("italic"), params, &ok);
977 setFontProperty(ret, &QFont::setPixelSize, QStringLiteral("pixelSize"), params, &ok);
978 setFontProperty(ret, &QFont::setPointSize, QStringLiteral("pointSize"), params, &ok);
979 setFontProperty(ret, &QFont::setStrikeOut, QStringLiteral("strikeout"), params, &ok);
980 setFontProperty(ret, &QFont::setStyleName, QStringLiteral("styleName"), params, &ok);
981 setFontProperty(ret, &QFont::setUnderline, QStringLiteral("underline"), params, &ok);
982 setFontProperty(ret, &QFont::setWeight, QStringLiteral("weight"), params, &ok);
983 setFontProperty(ret, &QFont::setWordSpacing, QStringLiteral("wordSpacing"), params, &ok);
984 setFontProperty(ret, &QFont::setHintingPreference, QStringLiteral("hintingPreference"), params, &ok);
985 setFontProperty(ret, &QFont::setKerning, QStringLiteral("kerning"), params, &ok);
986
987 {
988 const QJSValue vlspac = params.property(QStringLiteral("letterSpacing"));
989 if (vlspac.isNumber()) {
990 ret.setLetterSpacing(QFont::AbsoluteSpacing, vlspac.toNumber());
991 ok = true;
992 }
993 }
994
995 {
996 const QJSValue vshaping = params.property(QStringLiteral("preferShaping"));
997 if (vshaping.isBool()) {
998 const bool enable = vshaping.toBool();
999 const QFont::StyleStrategy strategy = ret.styleStrategy();
1000 if (enable)
1001 ret.setStyleStrategy(QFont::StyleStrategy(strategy & ~QFont::PreferNoShaping));
1002 else
1003 ret.setStyleStrategy(QFont::StyleStrategy(strategy | QFont::PreferNoShaping));
1004 ok = true;
1005 }
1006 }
1007
1008 {
1009 const QJSValue typoMetrics = params.property(QStringLiteral("preferTypoLineMetrics"));
1010 if (typoMetrics.isBool()) {
1011 const bool enable = typoMetrics.toBool();
1012 const QFont::StyleStrategy strategy = ret.styleStrategy();
1013 if (enable)
1014 ret.setStyleStrategy(QFont::StyleStrategy(strategy & ~QFont::PreferTypoLineMetrics));
1015 else
1016 ret.setStyleStrategy(QFont::StyleStrategy(strategy | QFont::PreferTypoLineMetrics));
1017 ok = true;
1018 }
1019 }
1020
1021 {
1022 const QJSValue ctxFontMerging = params.property(QStringLiteral("contextFontMerging"));
1023 if (ctxFontMerging.isBool()) {
1024 const bool enable = ctxFontMerging.toBool();
1025 const QFont::StyleStrategy strategy = ret.styleStrategy();
1026 if (enable)
1027 ret.setStyleStrategy(QFont::StyleStrategy(strategy | QFont::ContextFontMerging));
1028 else
1029 ret.setStyleStrategy(QFont::StyleStrategy(strategy & ~QFont::ContextFontMerging));
1030 ok = true;
1031 }
1032 }
1033
1034 {
1035 const QJSValue variableAxes = params.property(QStringLiteral("variableAxes"));
1036 if (variableAxes.isObject()) {
1037 QVariantMap variantMap = variableAxes.toVariant().toMap();
1038 for (auto [variableAxisName, variableAxisValue] : variantMap.asKeyValueRange()) {
1039 const auto maybeTag = QFont::Tag::fromString(variableAxisName);
1040 if (!maybeTag) {
1041 qWarning() << "Invalid variable axis" << variableAxisName << "ignored";
1042 continue;
1043 }
1044
1045 bool valueOk;
1046 float value = variableAxisValue.toFloat(&valueOk);
1047 if (!valueOk) {
1048 qWarning() << "Variable axis" << variableAxisName << "value" << variableAxisValue << "is not a floating point value.";
1049 continue;
1050 }
1051
1052 ret.setVariableAxis(*maybeTag, value);
1053 ok = true;
1054 }
1055 }
1056 }
1057
1058 {
1059 const QJSValue features = params.property(QStringLiteral("features"));
1060 if (features.isObject()) {
1061 QVariantMap variantMap = features.toVariant().toMap();
1062 for (auto [featureName, featureValue] : variantMap.asKeyValueRange()) {
1063 const auto maybeTag = QFont::Tag::fromString(featureName);
1064 if (!maybeTag) {
1065 qWarning() << "Invalid font feature" << featureName << "ignored";
1066 continue;
1067 }
1068
1069 bool valueOk;
1070 quint32 value = featureValue.toUInt(&valueOk);
1071 if (!valueOk) {
1072 qWarning() << "Font feature" << featureName << "value" << featureValue << "is not an integer.";
1073 continue;
1074 }
1075
1076 ret.setFeature(*maybeTag, value);
1077 ok = true;
1078 }
1079 }
1080 }
1081
1082 return ok ? ret : QVariant();
1083}
1084
1085QString QQuickFontValueType::toString() const
1086{
1087 return QLatin1String("QFont(%1)").arg(QFont::toString());
1088}
1089
1090QString QQuickFontValueType::family() const
1091{
1092 return QFont::family();
1093}
1094
1095void QQuickFontValueType::setFamily(const QString &family)
1096{
1097 QFont::setFamily(family);
1098}
1099
1100QString QQuickFontValueType::styleName() const
1101{
1102 return QFont::styleName();
1103}
1104
1105void QQuickFontValueType::setStyleName(const QString &style)
1106{
1107 QFont::setStyleName(style);
1108}
1109
1110bool QQuickFontValueType::bold() const
1111{
1112 return QFont::bold();
1113}
1114
1115void QQuickFontValueType::setBold(bool b)
1116{
1117 QFont::setBold(b);
1118}
1119
1120int QQuickFontValueType::weight() const
1121{
1122 return QFont::weight();
1123}
1124
1125void QQuickFontValueType::setWeight(int w)
1126{
1127 QFont::setWeight(QFont::Weight(w));
1128}
1129
1130bool QQuickFontValueType::italic() const
1131{
1132 return QFont::italic();
1133}
1134
1135void QQuickFontValueType::setItalic(bool b)
1136{
1137 QFont::setItalic(b);
1138}
1139
1140bool QQuickFontValueType::underline() const
1141{
1142 return QFont::underline();
1143}
1144
1145void QQuickFontValueType::setUnderline(bool b)
1146{
1147 QFont::setUnderline(b);
1148}
1149
1150bool QQuickFontValueType::overline() const
1151{
1152 return QFont::overline();
1153}
1154
1155void QQuickFontValueType::setOverline(bool b)
1156{
1157 QFont::setOverline(b);
1158}
1159
1160bool QQuickFontValueType::strikeout() const
1161{
1162 return QFont::strikeOut();
1163}
1164
1165void QQuickFontValueType::setStrikeout(bool b)
1166{
1167 QFont::setStrikeOut(b);
1168}
1169
1170qreal QQuickFontValueType::pointSize() const
1171{
1172 if (QFont::pointSizeF() == -1) {
1173 return QFont::pixelSize() * qreal(72.) / qreal(qt_defaultDpi());
1174 }
1175 return QFont::pointSizeF();
1176}
1177
1178void QQuickFontValueType::setPointSize(qreal size)
1179{
1180 if ((QFont::resolveMask() & QFont::SizeResolved) && QFont::pixelSize() != -1) {
1181 qWarning() << "Both point size and pixel size set. Using pixel size.";
1182 return;
1183 }
1184
1185 if (size >= 0.0) {
1186 QFont::setPointSizeF(size);
1187 }
1188}
1189
1190int QQuickFontValueType::pixelSize() const
1191{
1192 if (QFont::pixelSize() == -1) {
1193 return (QFont::pointSizeF() * qt_defaultDpi()) / qreal(72.);
1194 }
1195 return QFont::pixelSize();
1196}
1197
1198void QQuickFontValueType::setPixelSize(int size)
1199{
1200 if (size >0) {
1201 if ((QFont::resolveMask() & QFont::SizeResolved) && QFont::pointSizeF() != -1)
1202 qWarning() << "Both point size and pixel size set. Using pixel size.";
1203 QFont::setPixelSize(size);
1204 }
1205}
1206
1207QQuickFontEnums::Capitalization QQuickFontValueType::capitalization() const
1208{
1209 return (QQuickFontEnums::Capitalization)QFont::capitalization();
1210}
1211
1212void QQuickFontValueType::setCapitalization(QQuickFontEnums::Capitalization c)
1213{
1214 QFont::setCapitalization((QFont::Capitalization)c);
1215}
1216
1217qreal QQuickFontValueType::letterSpacing() const
1218{
1219 return QFont::letterSpacing();
1220}
1221
1222void QQuickFontValueType::setLetterSpacing(qreal size)
1223{
1224 QFont::setLetterSpacing(QFont::AbsoluteSpacing, size);
1225}
1226
1227qreal QQuickFontValueType::wordSpacing() const
1228{
1229 return QFont::wordSpacing();
1230}
1231
1232void QQuickFontValueType::setWordSpacing(qreal size)
1233{
1234 QFont::setWordSpacing(size);
1235}
1236
1237QQuickFontEnums::HintingPreference QQuickFontValueType::hintingPreference() const
1238{
1239 return QQuickFontEnums::HintingPreference(QFont::hintingPreference());
1240}
1241
1242void QQuickFontValueType::setHintingPreference(QQuickFontEnums::HintingPreference hintingPreference)
1243{
1244 QFont::setHintingPreference(QFont::HintingPreference(hintingPreference));
1245}
1246
1247bool QQuickFontValueType::kerning() const
1248{
1249 return QFont::kerning();
1250}
1251
1252void QQuickFontValueType::setKerning(bool b)
1253{
1254 QFont::setKerning(b);
1255}
1256
1257bool QQuickFontValueType::preferShaping() const
1258{
1259 return (QFont::styleStrategy() & QFont::PreferNoShaping) == 0;
1260}
1261
1262void QQuickFontValueType::setPreferShaping(bool enable)
1263{
1264 if (enable) {
1265 QFont::setStyleStrategy(
1266 static_cast<QFont::StyleStrategy>(QFont::styleStrategy() & ~QFont::PreferNoShaping));
1267 } else {
1268 QFont::setStyleStrategy(
1269 static_cast<QFont::StyleStrategy>(QFont::styleStrategy() | QFont::PreferNoShaping));
1270 }
1271}
1272
1273void QQuickFontValueType::setVariableAxes(const QVariantMap &variableAxes)
1274{
1275 QFont::clearVariableAxes();
1276 for (auto [variableAxisName, variableAxisValue] : variableAxes.asKeyValueRange()) {
1277 const auto maybeTag = QFont::Tag::fromString(variableAxisName);
1278 if (!maybeTag) {
1279 qWarning() << "Invalid variable axis" << variableAxisName << "ignored";
1280 continue;
1281 }
1282
1283 bool ok;
1284 float value = variableAxisValue.toFloat(&ok);
1285 if (!ok) {
1286 qWarning() << "Variable axis" << variableAxisName << "value" << variableAxisValue
1287 << "is not a floating point value.";
1288 continue;
1289 }
1290
1291 QFont::setVariableAxis(*maybeTag, value);
1292 }
1293}
1294
1295QVariantMap QQuickFontValueType::variableAxes() const
1296{
1297 QVariantMap ret;
1298 for (const auto &tag : QFont::variableAxisTags())
1299 ret.insert(QString::fromUtf8(tag.toString()), QFont::variableAxisValue(tag));
1300
1301 return ret;
1302}
1303
1304void QQuickFontValueType::setFeatures(const QVariantMap &features)
1305{
1306 QFont::clearFeatures();
1307 for (auto [featureName, featureValue] : features.asKeyValueRange()) {
1308 const auto maybeTag = QFont::Tag::fromString(featureName);
1309 if (!maybeTag) {
1310 qWarning() << "Invalid font feature" << featureName << "ignored";
1311 continue;
1312 }
1313
1314 bool ok;
1315 quint32 value = featureValue.toUInt(&ok);
1316 if (!ok) {
1317 qWarning() << "Font feature" << featureName << "value" << featureValue << "is not an integer.";
1318 continue;
1319 }
1320
1321 QFont::setFeature(*maybeTag, value);
1322 }
1323}
1324
1325QVariantMap QQuickFontValueType::features() const
1326{
1327 QVariantMap ret;
1328 for (const auto &tag : QFont::featureTags())
1329 ret.insert(QString::fromUtf8(tag.toString()), QFont::featureValue(tag));
1330
1331 return ret;
1332}
1333
1334bool QQuickFontValueType::contextFontMerging() const
1335{
1336 return (QFont::styleStrategy() & QFont::ContextFontMerging) != 0;
1337}
1338
1339void QQuickFontValueType::setContextFontMerging(bool enable)
1340{
1341 if (enable) {
1342 QFont::setStyleStrategy(
1343 static_cast<QFont::StyleStrategy>(
1344 QFont::styleStrategy() | QFont::ContextFontMerging));
1345 } else {
1346 QFont::setStyleStrategy(
1347 static_cast<QFont::StyleStrategy>(
1348 QFont::styleStrategy() & ~QFont::ContextFontMerging));
1349 }
1350}
1351
1352bool QQuickFontValueType::preferTypoLineMetrics() const
1353{
1354 return (QFont::styleStrategy() & QFont::PreferTypoLineMetrics) != 0;
1355}
1356
1357void QQuickFontValueType::setPreferTypoLineMetrics(bool enable)
1358{
1359 if (enable) {
1360 QFont::setStyleStrategy(
1361 static_cast<QFont::StyleStrategy>(
1362 QFont::styleStrategy() | QFont::PreferTypoLineMetrics));
1363 } else {
1364 QFont::setStyleStrategy(
1365 static_cast<QFont::StyleStrategy>(
1366 QFont::styleStrategy() & ~QFont::PreferTypoLineMetrics));
1367 }
1368}
1369
1370QVariant QQuickColorSpaceValueType::create(const QJSValue &params)
1371{
1372 if (!params.isObject())
1373 return QVariant();
1374
1375
1376 const QJSValue vName = params.property(QStringLiteral("namedColorSpace"));
1377 if (vName.isNumber())
1378 return QColorSpace((QColorSpace::NamedColorSpace)vName.toInt());
1379
1380 const QJSValue vPri = params.property(QStringLiteral("primaries"));
1381 const QJSValue vTra = params.property(QStringLiteral("transferFunction"));
1382 if (!vPri.isNumber() || !vTra.isNumber())
1383 return QVariant();
1384
1385 QColorSpace::Primaries pri = static_cast<QColorSpace::Primaries>(vPri.toInt());
1386 QColorSpace::TransferFunction tra = static_cast<QColorSpace::TransferFunction>(vTra.toInt());
1387 float gamma = 0.0f;
1388 if (tra == QColorSpace::TransferFunction::Gamma) {
1389 const QJSValue vGam = params.property(QStringLiteral("gamma"));
1390 if (!vGam.isNumber())
1391 return QVariant();
1392 gamma = vGam.toNumber();
1393 }
1394
1395 return QColorSpace(pri, tra, gamma);
1396}
1397
1398QQuickColorSpaceEnums::NamedColorSpace QQuickColorSpaceValueType::namedColorSpace() const noexcept
1399{
1400 if (const auto *p = QColorSpacePrivate::get(*this))
1401 return (QQuickColorSpaceEnums::NamedColorSpace)p->namedColorSpace;
1402 return QQuickColorSpaceEnums::Unknown;
1403}
1404void QQuickColorSpaceValueType::setNamedColorSpace(
1405 QQuickColorSpaceEnums::NamedColorSpace namedColorSpace)
1406{
1407 *static_cast<QColorSpace *>(this) = { (QColorSpace::NamedColorSpace)namedColorSpace };
1408}
1409
1410QQuickColorSpaceEnums::Primaries QQuickColorSpaceValueType::primaries() const noexcept
1411{
1412 return (QQuickColorSpaceEnums::Primaries)QColorSpace::primaries();
1413}
1414
1415void QQuickColorSpaceValueType::setPrimaries(QQuickColorSpaceEnums::Primaries primariesId)
1416{
1417 QColorSpace::setPrimaries((QColorSpace::Primaries)primariesId);
1418}
1419
1420QQuickColorSpaceEnums::TransferFunction QQuickColorSpaceValueType::transferFunction() const noexcept
1421{
1422 return (QQuickColorSpaceEnums::TransferFunction)QColorSpace::transferFunction();
1423}
1424
1425void QQuickColorSpaceValueType::setTransferFunction(
1426 QQuickColorSpaceEnums::TransferFunction transferFunction)
1427{
1428 QColorSpace::setTransferFunction(
1429 (QColorSpace::TransferFunction)transferFunction, QColorSpace::gamma());
1430}
1431
1432float QQuickColorSpaceValueType::gamma() const noexcept
1433{
1434 return QColorSpace::gamma();
1435}
1436
1437void QQuickColorSpaceValueType::setGamma(float gamma)
1438{
1439 QColorSpace::setTransferFunction(QColorSpace::transferFunction(), gamma);
1440}
1441
1442QT_END_NAMESPACE
1443
1444#include "moc_qquickvaluetypes_p.cpp"
void setFontProperty(QFont &font, void(QFont::*setter)(T value), QString name, const QJSValue &params, bool *ok)