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

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtdeclarative/src/quick/util/qquickvaluetypes.cpp