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