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