8#include <private/qtquickglobal_p.h>
9#include <private/qquickcontext2dtexture_p.h>
10#include <private/qquickitem_p.h>
11#if QT_CONFIG(quick_shadereffect)
12#include <QtQuick/private/qquickshadereffectsource_p.h>
14#include <qsgrendererinterface.h>
16#include <QtQuick/private/qsgcontext_p.h>
17#include <private/qquicksvgparser_p.h>
18#if QT_CONFIG(quick_path)
19#include <private/qquickpath_p.h>
21#include <private/qquickimage_p_p.h>
25#include <qqmlengine.h>
26#include <private/qv4domerrors_p.h>
27#include <private/qv4engine_p.h>
28#include <private/qv4object_p.h>
29#include <private/qv4qobjectwrapper_p.h>
30#include <private/qquickwindow_p.h>
32#include <private/qv4value_p.h>
33#include <private/qv4functionobject_p.h>
34#include <private/qv4objectproto_p.h>
35#include <private/qv4scopedvalue_p.h>
36#include <private/qlocale_tools_p.h>
38#include <QtCore/qmath.h>
39#include <QtCore/qvector.h>
40#include <QtCore/private/qnumeric_p.h>
41#include <QtCore/QRunnable>
42#include <QtGui/qguiapplication.h>
43#include <private/qguiapplication_p.h>
44#include <qpa/qplatformintegration.h>
46#include <private/qsgdefaultrendercontext_p.h>
48#include <QtCore/qpointer.h>
51#if defined(Q_OS_QNX) || defined(Q_OS_ANDROID)
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
95#define CHECK_CONTEXT(r) if (!r || !r->d()->context() || !r->d()->context()->bufferValid())
96 THROW_GENERIC_ERROR("Not a Context2D object");
98#define CHECK_CONTEXT_SETTER(r) if (!r || !r->d()->context() || !r->d()->context()->bufferValid())
99 THROW_GENERIC_ERROR("Not a Context2D object");
100#define qClamp(val, min, max) qMin(qMax(val, min), max)
101#define CHECK_RGBA(c) (c == '-' || c == '.' || (c >=0
&& c <= 9
))
104 QByteArray str = name.toQString().toUtf8();
106 char *p = str.data();
107 int len = str.size();
109 if (!p || len > 255 || len <= 7)
110 return QColor::fromString(p);
112 bool isRgb(
false), isHsl(
false), hasAlpha(
false);
115 while (isspace(*p)) p++;
116 if (strncmp(p,
"rgb", 3) == 0)
118 else if (strncmp(p,
"hsl", 3) == 0)
121 return QColor::fromString(p);
124 hasAlpha = (*p ==
'a') ?
true :
false;
130 int rh, gs, bl, alpha = 255;
133 while (isspace(*p)) p++;
134 rh = strtol(p, &p, 10);
136 rh = qRound(rh/100.0 * 255);
139 if (*p++ !=
',')
return QColor();
142 while (isspace(*p)) p++;
143 gs = strtol(p, &p, 10);
145 gs = qRound(gs/100.0 * 255);
148 if (*p++ !=
',')
return QColor();
151 while (isspace(*p)) p++;
152 bl = strtol(p, &p, 10);
154 bl = qRound(bl/100.0 * 255);
159 if (*p++!=
',')
return QColor();
160 while (isspace(*p)) p++;
162 alpha = qRound(qstrtod(p,
const_cast<
const char **>(&p), &ok) * 255);
165 if (*p !=
')')
return QColor();
167 return QColor::fromRgba(qRgba(
qClamp(rh, 0, 255),
qClamp(gs, 0, 255),
qClamp(bl, 0, 255),
qClamp(alpha, 0, 255)));
169 return QColor::fromHsl(
qClamp(rh, 0, 359),
qClamp(gs, 0, 255),
qClamp(bl, 0, 255),
qClamp(alpha, 0, 255));
177 float size = fontSizeToken.trimmed().toFloat(&ok);
181 qWarning().nospace() <<
"Context2D: A font size of " << fontSizeToken <<
" is invalid.";
186
187
188
189
192 const QStringView trimmedToken = fontSizeToken.trimmed();
193 const QStringView unitStr = trimmedToken.right(2);
194 const QStringView value = trimmedToken.left(trimmedToken.size() - 2);
197 if (unitStr == QLatin1String(
"px")) {
198 size = qParseFontSizeFromToken(value, ok);
200 font.setPixelSize(size);
203 }
else if (unitStr == QLatin1String(
"pt")) {
204 size = qParseFontSizeFromToken(value, ok);
206 font.setPointSize(size);
210 qWarning().nospace() <<
"Context2D: Invalid font size unit in font string.";
216
217
218
219
222 QStringList extractedFamilies;
224 QString currentFamily;
225 for (
int index = 0; index < fontFamiliesString.size(); ++index) {
226 const QChar ch = fontFamiliesString.at(index);
227 if (ch == u'"' || ch == u'\'') {
228 if (quoteIndex == -1) {
231 if (ch == fontFamiliesString.at(quoteIndex)) {
233 const QString family = fontFamiliesString.mid(quoteIndex + 1, index - quoteIndex - 1).toString();
234 extractedFamilies.push_back(family);
235 currentFamily.clear();
238 qWarning().nospace() <<
"Context2D: Mismatched quote in font string.";
239 return QStringList();
242 }
else if (ch == u' ' && quoteIndex == -1) {
244 if (!currentFamily.isEmpty()) {
246 extractedFamilies.push_back(currentFamily);
247 currentFamily.clear();
250 currentFamily.push_back(ch);
253 if (!currentFamily.isEmpty()) {
254 if (quoteIndex == -1) {
256 extractedFamilies.push_back(currentFamily);
258 qWarning().nospace() <<
"Context2D: Unclosed quote in font string.";
259 return QStringList();
262 if (extractedFamilies.isEmpty()) {
263 qWarning().nospace() <<
"Context2D: Missing or misplaced font family in font string"
264 <<
" (it must come after the font size).";
266 return extractedFamilies;
270
271
272
273
274
275
276
277
280 for (
const QString &fontFamilyToken : fontFamilyTokens) {
281 if (QFontDatabase::hasFamily(fontFamilyToken)) {
282 font.setFamily(fontFamilyToken);
288 if (fontFamilyToken.compare(QLatin1String(
"serif")) == 0) {
289 styleHint = QFont::Serif;
290 }
else if (fontFamilyToken.compare(QLatin1String(
"sans-serif")) == 0) {
291 styleHint = QFont::SansSerif;
292 }
else if (fontFamilyToken.compare(QLatin1String(
"cursive")) == 0) {
293 styleHint = QFont::Cursive;
294 }
else if (fontFamilyToken.compare(QLatin1String(
"monospace")) == 0) {
295 styleHint = QFont::Monospace;
296 }
else if (fontFamilyToken.compare(QLatin1String(
"fantasy")) == 0) {
297 styleHint = QFont::Fantasy;
299 if (styleHint != -1) {
301 tmp.setStyleHint(
static_cast<QFont::StyleHint>(styleHint));
302 font.setFamily(tmp.defaultFamily());
307 qWarning(
"Context2D: The font families specified are invalid: %s", qPrintable(fontFamilyTokens.join(QString()).trimmed()));
319#define Q_TRY_SET_TOKEN(token, value, setStatement) if
320 (!(usedTokens & token)) {
323}else {
324 qWarning().nospace() << "Context2D: Duplicate token " << QLatin1String(value) << " found in font string.";
325 return currentFont; \
326}
329
330
331
332
334 if (fontString.isEmpty()) {
335 qWarning().nospace() <<
"Context2D: Font string is empty.";
341 int fontSizeEnd = fontString.indexOf(QLatin1String(
"px"));
342 if (fontSizeEnd == -1)
343 fontSizeEnd = fontString.indexOf(QLatin1String(
"pt"));
344 if (fontSizeEnd == -1) {
345 qWarning().nospace() <<
"Context2D: Invalid font size unit in font string.";
349 int fontSizeStart = fontString.lastIndexOf(u' ', fontSizeEnd);
350 if (fontSizeStart == -1) {
363 if (!qSetFontSizeFromToken(newFont, QStringView{fontString}.mid(fontSizeStart, fontSizeEnd - fontSizeStart)))
367 QString remainingFontString = fontString;
368 remainingFontString.remove(fontSizeStart, fontSizeEnd - fontSizeStart);
369 QStringView remainingFontStringRef(remainingFontString);
372 const QStringView fontFamiliesString = remainingFontStringRef.mid(fontSizeStart);
373 remainingFontStringRef.truncate(fontSizeStart);
374 QStringList fontFamilies = qExtractFontFamiliesFromString(fontFamiliesString);
375 if (fontFamilies.isEmpty()) {
378 if (!qSetFontFamilyFromTokens(newFont, fontFamilies))
382 const QStringView trimmedTokensStr = remainingFontStringRef.trimmed();
383 if (trimmedTokensStr.isEmpty()) {
387 const auto tokens = trimmedTokensStr.split(QLatin1Char(
' '));
391 for (
const QStringView &token : tokens) {
392 if (token.compare(QLatin1String(
"normal")) == 0) {
393 if (!(usedTokens & FontStyle) || !(usedTokens & FontVariant) || !(usedTokens & FontWeight)) {
395 if (!(usedTokens & FontStyle)) {
397 usedTokens = usedTokens | FontStyle;
398 }
else if (!(usedTokens & FontVariant)) {
400 usedTokens |= FontVariant;
401 }
else if (!(usedTokens & FontWeight)) {
403 usedTokens |= FontWeight;
406 qWarning().nospace() <<
"Context2D: Duplicate token \"normal\" found in font string.";
409 }
else if (token.compare(QLatin1String(
"bold")) == 0) {
411 }
else if (token.compare(QLatin1String(
"italic")) == 0) {
412 Q_TRY_SET_TOKEN(FontStyle,
"italic", newFont.setStyle(QFont::StyleItalic))
413 }
else if (token.compare(QLatin1String(
"oblique")) == 0) {
414 Q_TRY_SET_TOKEN(FontStyle,
"oblique", newFont.setStyle(QFont::StyleOblique))
415 }
else if (token.compare(QLatin1String(
"small-caps")) == 0) {
416 Q_TRY_SET_TOKEN(FontVariant,
"small-caps", newFont.setCapitalization(QFont::SmallCaps))
418 bool conversionOk =
false;
419 int weight = token.toInt(&conversionOk);
422 newFont.setWeight(QFont::Weight(weight)))
425 qWarning().nospace() <<
"Context2D: Invalid or misplaced token " << token
426 <<
" found in font string.";
467 *m_context = context;
469 m_context =
new QPointer<QQuickContext2D>(context);
473 QPointer<QQuickContext2D>* m_context;
477 void init() { Object::init(); }
501 auto *mm = internalClass->engine->memoryManager;
502 mm->changeUnmanagedHeapSizeUsage(-image->sizeInBytes());
514 static void markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack) {
516 Object::markObjects(that, markStack);
562#if QT_CONFIG(quick_path)
703 int delta = radius ? radius : qFloor(qSqrt(weights.size()) / qreal(2));
704 int filterDim = 2 * delta + 1;
706 QImage dst = QImage(src.size(), src.format());
709 int h = src.height();
711 const QRgb *sr = (
const QRgb *)(src.constBits());
712 int srcStride = src.bytesPerLine() / 4;
714 QRgb *dr = (QRgb*)dst.bits();
715 int dstStride = dst.bytesPerLine() / 4;
717 for (
int y = 0; y < h; ++y) {
718 for (
int x = 0; x < w; ++x) {
732 for (
int cy = 0; cy < filterDim; ++cy) {
733 int scy = sy + cy - delta;
735 if (scy < 0 || scy >= h)
738 const QRgb *sry = sr + scy * srcStride;
740 for (
int cx = 0; cx < filterDim; ++cx) {
741 int scx = sx + cx - delta;
743 if (scx < 0 || scx >= w)
746 const QRgb col = sry[scx];
750 green += qGreen(col);
752 alpha += qAlpha(col);
754 qreal wt = weights[cy * filterDim + cx];
756 redF += qRed(col) * wt;
757 greenF += qGreen(col) * wt;
758 blueF += qBlue(col) * wt;
759 alphaF += qAlpha(col) * wt;
765 dr[x] = qRgba(qRound(red * weights[0]), qRound(green * weights[0]), qRound(blue * weights[0]), qRound(alpha * weights[0]));
767 dr[x] = qRgba(qRound(redF), qRound(greenF), qRound(blueF), qRound(alphaF));
778 int passes = quality? 3: 1;
779 int filterSize = 2 * radius + 1;
780 for (
int i = 0; i < passes; ++i)
781 image = qt_image_convolute_filter(image, QVector<qreal>() << 1.0 / (filterSize * filterSize), radius);
786 if (compositeOperator == QLatin1String(
"source-over")) {
787 return QPainter::CompositionMode_SourceOver;
788 }
else if (compositeOperator == QLatin1String(
"source-out")) {
789 return QPainter::CompositionMode_SourceOut;
790 }
else if (compositeOperator == QLatin1String(
"source-in")) {
791 return QPainter::CompositionMode_SourceIn;
792 }
else if (compositeOperator == QLatin1String(
"source-atop")) {
793 return QPainter::CompositionMode_SourceAtop;
794 }
else if (compositeOperator == QLatin1String(
"destination-atop")) {
795 return QPainter::CompositionMode_DestinationAtop;
796 }
else if (compositeOperator == QLatin1String(
"destination-in")) {
797 return QPainter::CompositionMode_DestinationIn;
798 }
else if (compositeOperator == QLatin1String(
"destination-out")) {
799 return QPainter::CompositionMode_DestinationOut;
800 }
else if (compositeOperator == QLatin1String(
"destination-over")) {
801 return QPainter::CompositionMode_DestinationOver;
802 }
else if (compositeOperator == QLatin1String(
"lighter")) {
803 return QPainter::CompositionMode_Plus;
804 }
else if (compositeOperator == QLatin1String(
"copy")) {
805 return QPainter::CompositionMode_Source;
806 }
else if (compositeOperator == QLatin1String(
"xor")) {
807 return QPainter::CompositionMode_Xor;
808 }
else if (compositeOperator == QLatin1String(
"qt-clear")) {
809 return QPainter::CompositionMode_Clear;
810 }
else if (compositeOperator == QLatin1String(
"qt-destination")) {
811 return QPainter::CompositionMode_Destination;
812 }
else if (compositeOperator == QLatin1String(
"qt-multiply")) {
813 return QPainter::CompositionMode_Multiply;
814 }
else if (compositeOperator == QLatin1String(
"qt-screen")) {
815 return QPainter::CompositionMode_Screen;
816 }
else if (compositeOperator == QLatin1String(
"qt-overlay")) {
817 return QPainter::CompositionMode_Overlay;
818 }
else if (compositeOperator == QLatin1String(
"qt-darken")) {
819 return QPainter::CompositionMode_Darken;
820 }
else if (compositeOperator == QLatin1String(
"qt-lighten")) {
821 return QPainter::CompositionMode_Lighten;
822 }
else if (compositeOperator == QLatin1String(
"qt-color-dodge")) {
823 return QPainter::CompositionMode_ColorDodge;
824 }
else if (compositeOperator == QLatin1String(
"qt-color-burn")) {
825 return QPainter::CompositionMode_ColorBurn;
826 }
else if (compositeOperator == QLatin1String(
"qt-hard-light")) {
827 return QPainter::CompositionMode_HardLight;
828 }
else if (compositeOperator == QLatin1String(
"qt-soft-light")) {
829 return QPainter::CompositionMode_SoftLight;
830 }
else if (compositeOperator == QLatin1String(
"qt-difference")) {
831 return QPainter::CompositionMode_Difference;
832 }
else if (compositeOperator == QLatin1String(
"qt-exclusion")) {
833 return QPainter::CompositionMode_Exclusion;
835 return QPainter::CompositionMode_SourceOver;
841 case QPainter::CompositionMode_SourceOver:
842 return QStringLiteral(
"source-over");
843 case QPainter::CompositionMode_DestinationOver:
844 return QStringLiteral(
"destination-over");
845 case QPainter::CompositionMode_Clear:
846 return QStringLiteral(
"qt-clear");
847 case QPainter::CompositionMode_Source:
848 return QStringLiteral(
"copy");
849 case QPainter::CompositionMode_Destination:
850 return QStringLiteral(
"qt-destination");
851 case QPainter::CompositionMode_SourceIn:
852 return QStringLiteral(
"source-in");
853 case QPainter::CompositionMode_DestinationIn:
854 return QStringLiteral(
"destination-in");
855 case QPainter::CompositionMode_SourceOut:
856 return QStringLiteral(
"source-out");
857 case QPainter::CompositionMode_DestinationOut:
858 return QStringLiteral(
"destination-out");
859 case QPainter::CompositionMode_SourceAtop:
860 return QStringLiteral(
"source-atop");
861 case QPainter::CompositionMode_DestinationAtop:
862 return QStringLiteral(
"destination-atop");
863 case QPainter::CompositionMode_Xor:
864 return QStringLiteral(
"xor");
865 case QPainter::CompositionMode_Plus:
866 return QStringLiteral(
"lighter");
867 case QPainter::CompositionMode_Multiply:
868 return QStringLiteral(
"qt-multiply");
869 case QPainter::CompositionMode_Screen:
870 return QStringLiteral(
"qt-screen");
871 case QPainter::CompositionMode_Overlay:
872 return QStringLiteral(
"qt-overlay");
873 case QPainter::CompositionMode_Darken:
874 return QStringLiteral(
"qt-darken");
875 case QPainter::CompositionMode_Lighten:
876 return QStringLiteral(
"lighter");
877 case QPainter::CompositionMode_ColorDodge:
878 return QStringLiteral(
"qt-color-dodge");
879 case QPainter::CompositionMode_ColorBurn:
880 return QStringLiteral(
"qt-color-burn");
881 case QPainter::CompositionMode_HardLight:
882 return QStringLiteral(
"qt-hard-light");
883 case QPainter::CompositionMode_SoftLight:
884 return QStringLiteral(
"qt-soft-light");
885 case QPainter::CompositionMode_Difference:
886 return QStringLiteral(
"qt-difference");
887 case QPainter::CompositionMode_Exclusion:
888 return QStringLiteral(
"qt-exclusion");
901 static bool virtualPut(QV4::Managed *m, QV4::PropertyKey id,
const QV4::Value &value, Value *receiver);
910 QV4::Scope scope(internalClass->engine);
911 QV4::ScopedObject o(scope,
this);
912 o->setArrayType(QV4::Heap::ArrayData::Custom);
930 pixelData = QV4::Value::undefinedValue();
932 QV4::Scope scope(internalClass->engine);
933 QV4::ScopedObject o(scope,
this);
935 o->defineAccessorProperty(QStringLiteral(
"width"), ::QQuickJSContext2DImageData::method_get_width,
nullptr);
936 o->defineAccessorProperty(QStringLiteral(
"height"), ::QQuickJSContext2DImageData::method_get_height,
nullptr);
937 o->defineAccessorProperty(QStringLiteral(
"data"), ::QQuickJSContext2DImageData::method_get_data,
nullptr);
944 QV4::Scope scope(v4);
946 QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, scope.engine->memoryManager->allocate<QQuickJSContext2DPixelData>());
947 v4->memoryManager->changeUnmanagedHeapSizeUsage(image.sizeInBytes());
948 QV4::ScopedObject p(scope, ed->pixelArrayProto.value());
949 pixelData->setPrototypeOf(p);
951 if (image.isNull()) {
952 *pixelData->d()->image = QImage(qRound(w), qRound(h), QImage::Format_ARGB32);
953 pixelData->d()->image->fill(0x00000000);
956 Q_ASSERT(qAbs(image.width() - qRound(w * image.devicePixelRatio())) <= 1 && qAbs(image.height() - qRound(h * image.devicePixelRatio())) <= 1);
957 *pixelData->d()->image = image.format() == QImage::Format_ARGB32 ? std::move(image) : std::move(image).convertToFormat(QImage::Format_ARGB32);
960 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, scope.engine->memoryManager->allocate<QQuickJSContext2DImageData>());
961 imageData->d()->pixelData = pixelData.asReturnedValue();
962 return imageData.asReturnedValue();
968
969
970
971
972
973QV4::ReturnedValue
QQuickJSContext2DPrototype::method_get_canvas(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
976 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
979 RETURN_RESULT(QV4::QObjectWrapper::wrap(scope.engine, r->d()->context()->canvas()));
983
984
985
986
987
988QV4::ReturnedValue
QQuickJSContext2DPrototype::method_restore(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
991 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
994 r->d()->context()->popState();
995 RETURN_RESULT(thisObject->asReturnedValue());
999
1000
1001
1004 QV4::Scope scope(b);
1005 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1008 r->d()->context()->reset();
1010 RETURN_RESULT(thisObject->asReturnedValue());
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1045 QV4::Scope scope(b);
1046 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1049 r->d()->context()->pushState();
1051 RETURN_RESULT(*thisObject);
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072QV4::ReturnedValue
QQuickJSContext2DPrototype::method_rotate(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1074 QV4::Scope scope(b);
1075 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1079 r->d()->context()->rotate(argv[0].toNumber());
1080 RETURN_RESULT(*thisObject);
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100QV4::ReturnedValue
QQuickJSContext2DPrototype::method_scale(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1102 QV4::Scope scope(b);
1103 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1108 r->d()->context()->scale(argv[0].toNumber(), argv[1].toNumber());
1109 RETURN_RESULT(*thisObject);
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149QV4::ReturnedValue
QQuickJSContext2DPrototype::method_setTransform(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1151 QV4::Scope scope(b);
1152 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1157 r->d()->context()->setTransform( argv[0].toNumber()
1158 , argv[1].toNumber()
1159 , argv[2].toNumber()
1160 , argv[3].toNumber()
1161 , argv[4].toNumber()
1162 , argv[5].toNumber());
1164 RETURN_RESULT(*thisObject);
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182QV4::ReturnedValue
QQuickJSContext2DPrototype::method_transform(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1184 QV4::Scope scope(b);
1185 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1189 r->d()->context()->transform( argv[0].toNumber()
1190 , argv[1].toNumber()
1191 , argv[2].toNumber()
1192 , argv[3].toNumber()
1193 , argv[4].toNumber()
1194 , argv[5].toNumber());
1196 RETURN_RESULT(*thisObject);
1201
1202
1203
1204
1205
1206
1207
1208
1209QV4::ReturnedValue
QQuickJSContext2DPrototype::method_translate(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1211 QV4::Scope scope(b);
1212 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1216 r->d()->context()->translate(argv[0].toNumber(), argv[1].toNumber());
1217 RETURN_RESULT(*thisObject);
1223
1224
1225
1226
1227
1228
1229
1230QV4::ReturnedValue
QQuickJSContext2DPrototype::method_resetTransform(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1232 QV4::Scope scope(b);
1233 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1236 r->d()->context()->setTransform(1, 0, 0, 1, 0, 0);
1238 RETURN_RESULT(*thisObject);
1244
1245
1246
1247
1248
1249QV4::ReturnedValue
QQuickJSContext2DPrototype::method_shear(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1251 QV4::Scope scope(b);
1252 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1256 r->d()->context()->shear(argv[0].toNumber(), argv[1].toNumber());
1258 RETURN_RESULT(*thisObject);
1264
1265
1266
1267
1268
1269
1270QV4::ReturnedValue
QQuickJSContext2D::method_get_globalAlpha(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1272 QV4::Scope scope(b);
1273 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1276 RETURN_RESULT(QV4::Encode(r->d()->context()->state.globalAlpha));
1279QV4::ReturnedValue
QQuickJSContext2D::method_set_globalAlpha(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1281 QV4::Scope scope(b);
1282 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1285 double globalAlpha = argc ? argv[0].toNumber() : qt_qnan();
1288 if (!qt_is_finite(globalAlpha))
1291 if (globalAlpha >= 0.0 && globalAlpha <= 1.0 && r->d()->context()->state.globalAlpha != globalAlpha) {
1292 r->d()->context()->state.globalAlpha = globalAlpha;
1293 r->d()->context()->buffer()->setGlobalAlpha(r->d()->context()->state.globalAlpha);
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376QV4::ReturnedValue
QQuickJSContext2D::method_get_globalCompositeOperation(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1378 QV4::Scope scope(b);
1379 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1382 RETURN_RESULT(scope.engine->newString(qt_composite_mode_to_string(r->d()->context()->state.globalCompositeOperation)));
1385QV4::ReturnedValue
QQuickJSContext2D::method_set_globalCompositeOperation(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1387 QV4::Scope scope(b);
1388 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1394 QString mode = argv[0].toQString();
1395 QPainter::CompositionMode cm = qt_composite_mode_from_string(mode);
1396 if (cm == QPainter::CompositionMode_SourceOver && mode != QLatin1String(
"source-over"))
1399 if (cm != r->d()->context()->state.globalCompositeOperation) {
1400 r->d()->context()->state.globalCompositeOperation = cm;
1401 r->d()->context()->buffer()->setGlobalCompositeOperation(cm);
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430QV4::ReturnedValue
QQuickJSContext2D::method_get_fillStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1432 QV4::Scope scope(b);
1433 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1436 const QColor color = r->d()->context()->state.fillStyle.color().toRgb();
1437 if (color.isValid()) {
1438 if (color.alpha() == 255)
1439 RETURN_RESULT(scope.engine->newString(color.name()));
1440 QString alphaString = QString::number(color.alphaF(),
'f');
1441 while (alphaString.endsWith(QLatin1Char(
'0')))
1442 alphaString.chop(1);
1443 if (alphaString.endsWith(QLatin1Char(
'.')))
1444 alphaString += QLatin1Char(
'0');
1445 QString str = QString::fromLatin1(
"rgba(%1, %2, %3, %4)").arg(color.red()).arg(color.green()).arg(color.blue()).arg(alphaString);
1446 RETURN_RESULT(scope.engine->newString(str));
1448 RETURN_RESULT(r->d()->context()->m_fillStyle.value());
1451QV4::ReturnedValue
QQuickJSContext2D::method_set_fillStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1453 QV4::Scope scope(b);
1454 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1457 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
1459 if (value->as<Object>()) {
1460 QColor color = QV4::ExecutionEngine::toVariant(value, QMetaType::fromType<QColor>()).value<QColor>();
1461 if (color.isValid()) {
1462 r->d()->context()->state.fillStyle = color;
1463 r->d()->context()->buffer()->setFillStyle(color);
1464 r->d()->context()->m_fillStyle.set(scope.engine, value);
1466 QV4::Scoped<QQuickContext2DStyle> style(scope, value->as<QQuickContext2DStyle>());
1467 if (style && *style->d()->brush != r->d()->context()->state.fillStyle) {
1468 r->d()->context()->state.fillStyle = *style->d()->brush;
1469 r->d()->context()->buffer()->setFillStyle(*style->d()->brush, style->d()->patternRepeatX, style->d()->patternRepeatY);
1470 r->d()->context()->m_fillStyle.set(scope.engine, value);
1471 r->d()->context()->state.fillPatternRepeatX = style->d()->patternRepeatX;
1472 r->d()->context()->state.fillPatternRepeatY = style->d()->patternRepeatY;
1475 }
else if (value->isString()) {
1476 QColor color = qt_color_from_string(value);
1477 if (color.isValid() && r->d()->context()->state.fillStyle != QBrush(color)) {
1478 r->d()->context()->state.fillStyle = QBrush(color);
1479 r->d()->context()->buffer()->setFillStyle(r->d()->context()->state.fillStyle);
1480 r->d()->context()->m_fillStyle.set(scope.engine, value);
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498QV4::ReturnedValue
QQuickJSContext2D::method_get_fillRule(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1500 QV4::Scope scope(b);
1501 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1504 RETURN_RESULT(scope.engine->fromVariant(r->d()->context()->state.fillRule));
1507QV4::ReturnedValue
QQuickJSContext2D::method_set_fillRule(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1509 QV4::Scope scope(b);
1510 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1513 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
1515 if ((value->isString() && value->toQString() == QLatin1String(
"WindingFill"))
1516 || (value->isInt32() && value->integerValue() == Qt::WindingFill)) {
1517 r->d()->context()->state.fillRule = Qt::WindingFill;
1518 }
else if ((value->isString() && value->toQStringNoThrow() == QLatin1String(
"OddEvenFill"))
1519 || (value->isInt32() && value->integerValue() == Qt::OddEvenFill)) {
1520 r->d()->context()->state.fillRule = Qt::OddEvenFill;
1524 r->d()->context()->m_path.setFillRule(r->d()->context()->state.fillRule);
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540QV4::ReturnedValue
QQuickJSContext2D::method_get_strokeStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1542 QV4::Scope scope(b);
1543 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1546 const QColor color = r->d()->context()->state.strokeStyle.color().toRgb();
1547 if (color.isValid()) {
1548 if (color.alpha() == 255)
1549 RETURN_RESULT(scope.engine->newString(color.name()));
1550 QString alphaString = QString::number(color.alphaF(),
'f');
1551 while (alphaString.endsWith(QLatin1Char(
'0')))
1552 alphaString.chop(1);
1553 if (alphaString.endsWith(QLatin1Char(
'.')))
1554 alphaString += QLatin1Char(
'0');
1555 QString str = QString::fromLatin1(
"rgba(%1, %2, %3, %4)").arg(color.red()).arg(color.green()).arg(color.blue()).arg(alphaString);
1556 RETURN_RESULT(scope.engine->newString(str));
1558 RETURN_RESULT(r->d()->context()->m_strokeStyle.value());
1561QV4::ReturnedValue
QQuickJSContext2D::method_set_strokeStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1563 QV4::Scope scope(b);
1564 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1567 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
1569 if (value->as<Object>()) {
1570 QColor color = QV4::ExecutionEngine::toVariant(value, QMetaType::fromType<QColor>()).value<QColor>();
1571 if (color.isValid()) {
1572 r->d()->context()->state.strokeStyle = color;
1573 r->d()->context()->buffer()->setStrokeStyle(color);
1574 r->d()->context()->m_strokeStyle.set(scope.engine, value);
1576 QV4::Scoped<QQuickContext2DStyle> style(scope, value->as<QQuickContext2DStyle>());
1577 if (style && *style->d()->brush != r->d()->context()->state.strokeStyle) {
1578 r->d()->context()->state.strokeStyle = *style->d()->brush;
1579 r->d()->context()->buffer()->setStrokeStyle(*style->d()->brush, style->d()->patternRepeatX, style->d()->patternRepeatY);
1580 r->d()->context()->m_strokeStyle.set(scope.engine, value);
1581 r->d()->context()->state.strokePatternRepeatX = style->d()->patternRepeatX;
1582 r->d()->context()->state.strokePatternRepeatY = style->d()->patternRepeatY;
1583 }
else if (!style && r->d()->context()->state.strokeStyle != QBrush(QColor())) {
1586 r->d()->context()->state.strokeStyle = QBrush(QColor());
1587 r->d()->context()->buffer()->setStrokeStyle(r->d()->context()->state.strokeStyle);
1588 r->d()->context()->m_strokeStyle.set(scope.engine, value);
1591 }
else if (value->isString()) {
1592 QColor color = qt_color_from_string(value);
1593 if (color.isValid() && r->d()->context()->state.strokeStyle != QBrush(color)) {
1594 r->d()->context()->state.strokeStyle = QBrush(color);
1595 r->d()->context()->buffer()->setStrokeStyle(r->d()->context()->state.strokeStyle);
1596 r->d()->context()->m_strokeStyle.set(scope.engine, value);
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1619QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createLinearGradient(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1621 QV4::Scope scope(b);
1622 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1626 qreal x0 = argv[0].toNumber();
1627 qreal y0 = argv[1].toNumber();
1628 qreal x1 = argv[2].toNumber();
1629 qreal y1 = argv[3].toNumber();
1631 if (!qt_is_finite(x0)
1632 || !qt_is_finite(y0)
1633 || !qt_is_finite(x1)
1634 || !qt_is_finite(y1)) {
1635 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createLinearGradient(): Incorrect arguments")
1639 QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocate<QQuickContext2DStyle>());
1640 QV4::ScopedObject p(scope, ed->gradientProto.value());
1641 gradient->setPrototypeOf(p);
1642 *gradient->d()->brush = QLinearGradient(x0, y0, x1, y1);
1643 RETURN_RESULT(*gradient);
1646 RETURN_RESULT(*thisObject);
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1666QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createRadialGradient(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1668 QV4::Scope scope(b);
1669 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1673 qreal x0 = argv[0].toNumber();
1674 qreal y0 = argv[1].toNumber();
1675 qreal r0 = argv[2].toNumber();
1676 qreal x1 = argv[3].toNumber();
1677 qreal y1 = argv[4].toNumber();
1678 qreal r1 = argv[5].toNumber();
1680 if (!qt_is_finite(x0)
1681 || !qt_is_finite(y0)
1682 || !qt_is_finite(x1)
1683 || !qt_is_finite(r0)
1684 || !qt_is_finite(r1)
1685 || !qt_is_finite(y1)) {
1686 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createRadialGradient(): Incorrect arguments")
1689 if (r0 < 0 || r1 < 0)
1690 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"createRadialGradient(): Incorrect arguments")
1692 QQuickContext2DEngineData *ed = engineData(scope.engine);
1694 QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocate<QQuickContext2DStyle>());
1695 QV4::ScopedObject p(scope, ed->gradientProto.value());
1696 gradient->setPrototypeOf(p);
1697 *gradient->d()->brush = QRadialGradient(QPointF(x1, y1), r1, QPointF(x0, y0), r0);
1698 RETURN_RESULT(*gradient);
1701 RETURN_RESULT(*thisObject);
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1720QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createConicalGradient(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1722 QV4::Scope scope(b);
1723 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1727 qreal x = argv[0].toNumber();
1728 qreal y = argv[1].toNumber();
1729 qreal angle = qRadiansToDegrees(argv[2].toNumber());
1730 if (!qt_is_finite(x) || !qt_is_finite(y)) {
1731 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createConicalGradient(): Incorrect arguments");
1734 if (!qt_is_finite(angle)) {
1735 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"createConicalGradient(): Incorrect arguments");
1740 QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocate<QQuickContext2DStyle>());
1741 QV4::ScopedObject p(scope, ed->gradientProto.value());
1742 gradient->setPrototypeOf(p);
1743 *gradient->d()->brush = QConicalGradient(x, y, angle);
1744 RETURN_RESULT(*gradient);
1747 RETURN_RESULT(*thisObject);
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createPattern(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1796 QV4::Scope scope(b);
1797 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1801 QV4::Scoped<QQuickContext2DStyle> pattern(scope, scope.engine->memoryManager->allocate<QQuickContext2DStyle>());
1803 QColor color = QV4::ExecutionEngine::toVariant(
1804 argv[0], QMetaType::fromType<QColor>()).value<QColor>();
1805 if (color.isValid()) {
1806 int patternMode = argv[1].toInt32();
1807 Qt::BrushStyle style = Qt::SolidPattern;
1808 if (patternMode >= 0 && patternMode < Qt::LinearGradientPattern) {
1809 style =
static_cast<Qt::BrushStyle>(patternMode);
1811 *pattern->d()->brush = QBrush(color, style);
1813 QImage patternTexture;
1815 if (
const QV4::Object *o = argv[0].as<Object>()) {
1816 QV4::ScopedString s(scope, scope.engine->newString(QStringLiteral(
"data")));
1817 QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, o->get(s));
1819 patternTexture = *pixelData->d()->image;
1822 patternTexture = r->d()->context()->createPixmap(QUrl(argv[0].toQStringNoThrow()))->image();
1825 if (!patternTexture.isNull()) {
1826 pattern->d()->brush->setTextureImage(patternTexture);
1828 QString repetition = argv[1].toQStringNoThrow();
1829 if (repetition == QLatin1String(
"repeat") || repetition.isEmpty()) {
1830 pattern->d()->patternRepeatX =
true;
1831 pattern->d()->patternRepeatY =
true;
1832 }
else if (repetition == QLatin1String(
"repeat-x")) {
1833 pattern->d()->patternRepeatX =
true;
1834 pattern->d()->patternRepeatY =
false;
1835 }
else if (repetition == QLatin1String(
"repeat-y")) {
1836 pattern->d()->patternRepeatX =
false;
1837 pattern->d()->patternRepeatY =
true;
1838 }
else if (repetition == QLatin1String(
"no-repeat")) {
1839 pattern->d()->patternRepeatX =
false;
1840 pattern->d()->patternRepeatY =
false;
1848 RETURN_RESULT(*pattern);
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873QV4::ReturnedValue
QQuickJSContext2D::method_get_lineCap(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1875 QV4::Scope scope(b);
1876 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1879 switch (r->d()->context()->state.lineCap) {
1881 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"round")));
1883 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"square")));
1888 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"butt")));
1891QV4::ReturnedValue
QQuickJSContext2D::method_set_lineCap(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1894 return QV4::Encode::undefined();
1896 QV4::Scope scope(b);
1897 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1900 QString lineCap = argv[0].toQString();
1901 Qt::PenCapStyle cap;
1902 if (lineCap == QLatin1String(
"round"))
1904 else if (lineCap == QLatin1String(
"butt"))
1906 else if (lineCap == QLatin1String(
"square"))
1907 cap = Qt::SquareCap;
1911 if (cap != r->d()->context()->state.lineCap) {
1912 r->d()->context()->state.lineCap = cap;
1913 r->d()->context()->buffer()->setLineCap(cap);
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934QV4::ReturnedValue
QQuickJSContext2D::method_get_lineJoin(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1936 QV4::Scope scope(b);
1937 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1940 switch (r->d()->context()->state.lineJoin) {
1942 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"round")));
1944 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"bevel")));
1949 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"miter")));
1952QV4::ReturnedValue
QQuickJSContext2D::method_set_lineJoin(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1954 QV4::Scope scope(b);
1955 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1961 QString lineJoin = argv[0].toQString();
1962 Qt::PenJoinStyle join;
1963 if (lineJoin == QLatin1String(
"round"))
1964 join = Qt::RoundJoin;
1965 else if (lineJoin == QLatin1String(
"bevel"))
1966 join = Qt::BevelJoin;
1967 else if (lineJoin == QLatin1String(
"miter"))
1968 join = Qt::SvgMiterJoin;
1972 if (join != r->d()->context()->state.lineJoin) {
1973 r->d()->context()->state.lineJoin = join;
1974 r->d()->context()->buffer()->setLineJoin(join);
1980
1981
1982
1983QV4::ReturnedValue
QQuickJSContext2D::method_get_lineWidth(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1985 QV4::Scope scope(b);
1986 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1989 RETURN_RESULT(QV4::Encode(r->d()->context()->state.lineWidth));
1992QV4::ReturnedValue
QQuickJSContext2D::method_set_lineWidth(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1994 QV4::Scope scope(b);
1995 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1998 qreal w = argc ? argv[0].toNumber() : -1;
2000 if (w > 0 && qt_is_finite(w) && w != r->d()->context()->state.lineWidth) {
2001 r->d()->context()->state.lineWidth = w;
2002 r->d()->context()->buffer()->setLineWidth(w);
2008
2009
2010
2011
2012QV4::ReturnedValue
QQuickJSContext2D::method_get_miterLimit(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2014 QV4::Scope scope(b);
2015 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2018 RETURN_RESULT(QV4::Encode(r->d()->context()->state.miterLimit));
2021QV4::ReturnedValue
QQuickJSContext2D::method_set_miterLimit(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2023 QV4::Scope scope(b);
2024 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2027 qreal ml = argc ? argv[0].toNumber() : -1;
2029 if (ml > 0 && qt_is_finite(ml) && ml != r->d()->context()->state.miterLimit) {
2030 r->d()->context()->state.miterLimit = ml;
2031 r->d()->context()->buffer()->setMiterLimit(ml);
2037
2038
2039
2040
2041
2042
2043QV4::ReturnedValue
QQuickJSContext2DPrototype::method_getLineDash(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2045 QV4::Scope scope(b);
2046 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2049 const QVector<qreal> pattern = r->d()->context()->state.lineDash;
2050 QV4::ScopedArrayObject array(scope, scope.engine->newArrayObject(pattern.size()));
2051 array->arrayReserve(pattern.size());
2052 for (
int i = 0; i < pattern.size(); i++)
2053 array->put(i, QV4::Value::fromDouble(pattern[i]));
2055 array->setArrayLengthUnchecked(pattern.size());
2057 RETURN_RESULT(*array);
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084QV4::ReturnedValue
QQuickJSContext2DPrototype::method_setLineDash(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2086 QV4::Scope scope(b);
2087 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2093 QV4::ScopedArrayObject array(scope, argv[0]);
2097 QV4::ScopedValue v(scope);
2098 const uint arrayLength = array->getLength();
2099 QVector<qreal> dashes;
2100 dashes.reserve(arrayLength);
2101 for (uint i = 0; i < arrayLength; ++i) {
2103 const double number = v->toNumber();
2105 if (!qt_is_finite(number) || (number < 0))
2108 dashes.append(v->toNumber());
2110 if (dashes.size() % 2 != 0) {
2114 r->d()->context()->state.lineDash = dashes;
2115 r->d()->context()->buffer()->setLineDash(dashes);
2121
2122
2123
2124
2125
2126
2127
2128
2129QV4::ReturnedValue
QQuickJSContext2D::method_get_lineDashOffset(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2131 QV4::Scope scope(b);
2132 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2135 RETURN_RESULT(QV4::Encode(r->d()->context()->state.lineDashOffset));
2138QV4::ReturnedValue
QQuickJSContext2D::method_set_lineDashOffset(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2140 QV4::Scope scope(b);
2141 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2144 const qreal offset = argc ? argv[0].toNumber() : -1;
2146 if (qt_is_finite(offset) && offset != r->d()->context()->state.lineDashOffset) {
2147 r->d()->context()->state.lineDashOffset = offset;
2148 r->d()->context()->buffer()->setLineDashOffset(offset);
2156
2157
2158
2159QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowBlur(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2161 QV4::Scope scope(b);
2162 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2165 RETURN_RESULT(QV4::Encode(r->d()->context()->state.shadowBlur));
2168QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowBlur(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2170 QV4::Scope scope(b);
2171 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2174 qreal blur = argc ? argv[0].toNumber() : -1;
2176 if (blur > 0 && qt_is_finite(blur) && blur != r->d()->context()->state.shadowBlur) {
2177 r->d()->context()->state.shadowBlur = blur;
2178 r->d()->context()->buffer()->setShadowBlur(blur);
2184
2185
2186
2187QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowColor(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2189 QV4::Scope scope(b);
2190 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2193 RETURN_RESULT(scope.engine->newString(r->d()->context()->state.shadowColor.name()));
2196QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowColor(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2198 QV4::Scope scope(b);
2199 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2204 color = qt_color_from_string(argv[0]);
2206 if (color.isValid() && color != r->d()->context()->state.shadowColor) {
2207 r->d()->context()->state.shadowColor = color;
2208 r->d()->context()->buffer()->setShadowColor(color);
2215
2216
2217
2218
2219
2220QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowOffsetX(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2222 QV4::Scope scope(b);
2223 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2226 RETURN_RESULT(QV4::Encode(r->d()->context()->state.shadowOffsetX));
2229QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowOffsetX(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2231 QV4::Scope scope(b);
2232 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2235 qreal offsetX = argc ? argv[0].toNumber() : qt_qnan();
2236 if (qt_is_finite(offsetX) && offsetX != r->d()->context()->state.shadowOffsetX) {
2237 r->d()->context()->state.shadowOffsetX = offsetX;
2238 r->d()->context()->buffer()->setShadowOffsetX(offsetX);
2243
2244
2245
2246
2247
2248QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowOffsetY(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2250 QV4::Scope scope(b);
2251 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2254 RETURN_RESULT(QV4::Encode(r->d()->context()->state.shadowOffsetY));
2257QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowOffsetY(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2259 QV4::Scope scope(b);
2260 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2263 qreal offsetY = argc ? argv[0].toNumber() : qt_qnan();
2264 if (qt_is_finite(offsetY) && offsetY != r->d()->context()->state.shadowOffsetY) {
2265 r->d()->context()->state.shadowOffsetY = offsetY;
2266 r->d()->context()->buffer()->setShadowOffsetY(offsetY);
2271#if QT_CONFIG(quick_path)
2272QV4::ReturnedValue QQuickJSContext2D::method_get_path(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2274 QV4::Scope scope(b);
2275 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2278 RETURN_RESULT(r->d()->context()->m_v4path.value());
2281QV4::ReturnedValue QQuickJSContext2D::method_set_path(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2283 QV4::Scope scope(b);
2284 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2285 CHECK_CONTEXT_SETTER(r)
2287 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
2288 r->d()->context()->beginPath();
2289 QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, value);
2290 if (!!qobjectWrapper) {
2291 if (QQuickPath *path = qobject_cast<QQuickPath*>(qobjectWrapper->object()))
2292 r->d()->context()->m_path = path->path();
2294 QString path =value->toQStringNoThrow();
2295 QQuickSvgParser::parsePathDataFast(path, r->d()->context()->m_path);
2297 r->d()->context()->m_v4path.set(scope.engine, value);
2304
2305
2306
2307
2308
2309QV4::ReturnedValue
QQuickJSContext2DPrototype::method_clearRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2311 QV4::Scope scope(b);
2312 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2317 r->d()->context()->clearRect(argv[0].toNumber(),
2320 argv[3].toNumber());
2322 RETURN_RESULT(*thisObject);
2326
2327
2328
2329
2330
2331
2332QV4::ReturnedValue
QQuickJSContext2DPrototype::method_fillRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2334 QV4::Scope scope(b);
2335 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2339 r->d()->context()->fillRect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2340 RETURN_RESULT(*thisObject);
2345
2346
2347
2348
2349
2350
2351
2352QV4::ReturnedValue
QQuickJSContext2DPrototype::method_strokeRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2354 QV4::Scope scope(b);
2355 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2359 r->d()->context()->strokeRect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2361 RETURN_RESULT(*thisObject);
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386QV4::ReturnedValue
QQuickJSContext2DPrototype::method_arc(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2388 QV4::Scope scope(b);
2389 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2393 bool antiClockwise =
false;
2396 antiClockwise = argv[5].toBoolean();
2398 qreal radius = argv[2].toNumber();
2400 if (qt_is_finite(radius) && radius < 0)
2401 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"Incorrect argument radius");
2403 r->d()->context()->arc(argv[0].toNumber(),
2411 RETURN_RESULT(*thisObject);
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438QV4::ReturnedValue
QQuickJSContext2DPrototype::method_arcTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2440 QV4::Scope scope(b);
2441 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2445 qreal radius = argv[4].toNumber();
2447 if (qt_is_finite(radius) && radius < 0)
2448 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"Incorrect argument radius");
2450 r->d()->context()->arcTo(argv[0].toNumber(),
2457 RETURN_RESULT(*thisObject);
2462
2463
2464
2465
2466QV4::ReturnedValue
QQuickJSContext2DPrototype::method_beginPath(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2468 QV4::Scope scope(b);
2469 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2472 r->d()->context()->beginPath();
2474 RETURN_RESULT(*thisObject);
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500QV4::ReturnedValue
QQuickJSContext2DPrototype::method_bezierCurveTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2502 QV4::Scope scope(b);
2503 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2507 qreal cp1x = argv[0].toNumber();
2508 qreal cp1y = argv[1].toNumber();
2509 qreal cp2x = argv[2].toNumber();
2510 qreal cp2y = argv[3].toNumber();
2511 qreal x = argv[4].toNumber();
2512 qreal y = argv[5].toNumber();
2514 if (!qt_is_finite(cp1x) || !qt_is_finite(cp1y) || !qt_is_finite(cp2x) || !qt_is_finite(cp2y) || !qt_is_finite(x) || !qt_is_finite(y))
2517 r->d()->context()->bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
2519 RETURN_RESULT(*thisObject);
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2548 QV4::Scope scope(b);
2549 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2552 r->d()->context()->clip();
2553 RETURN_RESULT(*thisObject);
2557
2558
2559
2560
2561
2562
2563QV4::ReturnedValue
QQuickJSContext2DPrototype::method_closePath(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2565 QV4::Scope scope(b);
2566 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2569 r->d()->context()->closePath();
2571 RETURN_RESULT(*thisObject);
2575
2576
2577
2578
2579
2580
2581
2582
2585 QV4::Scope scope(b);
2586 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2588 r->d()->context()->fill();
2589 RETURN_RESULT(*thisObject);
2593
2594
2595
2596
2597QV4::ReturnedValue
QQuickJSContext2DPrototype::method_lineTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2599 QV4::Scope scope(b);
2600 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2604 qreal x = argv[0].toNumber();
2605 qreal y = argv[1].toNumber();
2607 if (!qt_is_finite(x) || !qt_is_finite(y))
2610 r->d()->context()->lineTo(x, y);
2613 RETURN_RESULT(*thisObject);
2617
2618
2619
2620
2621QV4::ReturnedValue
QQuickJSContext2DPrototype::method_moveTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2623 QV4::Scope scope(b);
2624 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2628 qreal x = argv[0].toNumber();
2629 qreal y = argv[1].toNumber();
2631 if (!qt_is_finite(x) || !qt_is_finite(y))
2633 r->d()->context()->moveTo(x, y);
2636 RETURN_RESULT(*thisObject);
2640
2641
2642
2643
2644
2645
2646
2647QV4::ReturnedValue
QQuickJSContext2DPrototype::method_quadraticCurveTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2649 QV4::Scope scope(b);
2650 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2654 qreal cpx = argv[0].toNumber();
2655 qreal cpy = argv[1].toNumber();
2656 qreal x = argv[2].toNumber();
2657 qreal y = argv[3].toNumber();
2659 if (!qt_is_finite(cpx) || !qt_is_finite(cpy) || !qt_is_finite(x) || !qt_is_finite(y))
2662 r->d()->context()->quadraticCurveTo(cpx, cpy, x, y);
2665 RETURN_RESULT(*thisObject);
2669
2670
2671
2672
2673
2674QV4::ReturnedValue
QQuickJSContext2DPrototype::method_rect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2676 QV4::Scope scope(b);
2677 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2681 r->d()->context()->rect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2682 RETURN_RESULT(*thisObject);
2687
2688
2689
2690
2691
2692
2693QV4::ReturnedValue
QQuickJSContext2DPrototype::method_roundedRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2695 QV4::Scope scope(b);
2696 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2700 r->d()->context()->roundedRect(argv[0].toNumber()
2701 , argv[1].toNumber()
2702 , argv[2].toNumber()
2703 , argv[3].toNumber()
2704 , argv[4].toNumber()
2705 , argv[5].toNumber());
2706 RETURN_RESULT(*thisObject);
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720QV4::ReturnedValue
QQuickJSContext2DPrototype::method_ellipse(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2722 QV4::Scope scope(b);
2723 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2727 r->d()->context()->ellipse(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2729 RETURN_RESULT(*thisObject);
2734
2735
2736
2737
2738
2739
2740
2741
2742QV4::ReturnedValue
QQuickJSContext2DPrototype::method_text(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2744 QV4::Scope scope(b);
2745 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2749 qreal x = argv[1].toNumber();
2750 qreal y = argv[2].toNumber();
2752 if (!qt_is_finite(x) || !qt_is_finite(y))
2754 r->d()->context()->text(argv[0].toQStringNoThrow(), x, y);
2757 RETURN_RESULT(*thisObject);
2761
2762
2763
2764
2765
2766
2769 QV4::Scope scope(b);
2770 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2773 r->d()->context()->stroke();
2774 RETURN_RESULT(*thisObject);
2779
2780
2781
2782
2783
2784
2785QV4::ReturnedValue
QQuickJSContext2DPrototype::method_isPointInPath(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2787 QV4::Scope scope(b);
2788 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2791 bool pointInPath =
false;
2793 pointInPath = r->d()->context()->isPointInPath(argv[0].toNumber(), argv[1].toNumber());
2794 RETURN_RESULT(QV4::Value::fromBoolean(pointInPath).asReturnedValue());
2799 QV4::Scope scope(b);
2800 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"Context2D::drawFocusRing is not supported");
2803QV4::ReturnedValue
QQuickJSContext2DPrototype::method_setCaretSelectionRect(
const QV4::FunctionObject *b,
const QV4::Value *,
const QV4::Value *,
int)
2805 QV4::Scope scope(b);
2806 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"Context2D::setCaretSelectionRect is not supported");
2811 QV4::Scope scope(b);
2812 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"Context2D::caretBlinkRate is not supported");
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838QV4::ReturnedValue
QQuickJSContext2D::method_get_font(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2840 QV4::Scope scope(b);
2841 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2844 RETURN_RESULT(scope.engine->newString(r->d()->context()->state.font.toString()));
2847QV4::ReturnedValue
QQuickJSContext2D::method_set_font(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2849 QV4::Scope scope(b);
2850 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2853 QV4::ScopedString s(scope, argc ? argv[0] : QV4::Value::undefinedValue(), QV4::ScopedString::Convert);
2854 if (scope.hasException())
2856 QFont font = qt_font_from_string(s->toQString(), r->d()->context()->state.font);
2857 if (font != r->d()->context()->state.font) {
2858 r->d()->context()->state.font = font;
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878QV4::ReturnedValue
QQuickJSContext2D::method_get_textAlign(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2880 QV4::Scope scope(b);
2881 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2884 switch (r->d()->context()->state.textAlign) {
2885 case QQuickContext2D::End:
2886 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"end")));
2887 case QQuickContext2D::Left:
2888 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"left")));
2889 case QQuickContext2D::Right:
2890 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"right")));
2891 case QQuickContext2D::Center:
2892 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"center")));
2897 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"start")));
2900QV4::ReturnedValue
QQuickJSContext2D::method_set_textAlign(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2902 QV4::Scope scope(b);
2903 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2906 QV4::ScopedString s(scope, argc ? argv[0] : QV4::Value::undefinedValue(), QV4::ScopedString::Convert);
2907 if (scope.hasException())
2909 QString textAlign = s->toQString();
2912 if (textAlign == QLatin1String(
"start"))
2914 else if (textAlign == QLatin1String(
"end"))
2916 else if (textAlign == QLatin1String(
"left"))
2918 else if (textAlign == QLatin1String(
"right"))
2920 else if (textAlign == QLatin1String(
"center"))
2925 if (ta != r->d()->context()->state.textAlign)
2926 r->d()->context()->state.textAlign = ta;
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945QV4::ReturnedValue
QQuickJSContext2D::method_get_textBaseline(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2947 QV4::Scope scope(b);
2948 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2951 switch (r->d()->context()->state.textBaseline) {
2952 case QQuickContext2D::Hanging:
2953 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"hanging")));
2954 case QQuickContext2D::Top:
2955 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"top")));
2956 case QQuickContext2D::Bottom:
2957 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"bottom")));
2958 case QQuickContext2D::Middle:
2959 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"middle")));
2960 case QQuickContext2D::Alphabetic:
2964 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"alphabetic")));
2967QV4::ReturnedValue
QQuickJSContext2D::method_set_textBaseline(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2969 QV4::Scope scope(b);
2970 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2972 QV4::ScopedString s(scope, argc ? argv[0] : QV4::Value::undefinedValue(), QV4::ScopedString::Convert);
2973 if (scope.hasException())
2975 QString textBaseline = s->toQString();
2977 QQuickContext2D::TextBaseLineType tb;
2978 if (textBaseline == QLatin1String(
"alphabetic"))
2979 tb = QQuickContext2D::Alphabetic;
2980 else if (textBaseline == QLatin1String(
"hanging"))
2981 tb = QQuickContext2D::Hanging;
2982 else if (textBaseline == QLatin1String(
"top"))
2983 tb = QQuickContext2D::Top;
2984 else if (textBaseline == QLatin1String(
"bottom"))
2985 tb = QQuickContext2D::Bottom;
2986 else if (textBaseline == QLatin1String(
"middle"))
2987 tb = QQuickContext2D::Middle;
2991 if (tb != r->d()->context()->state.textBaseline)
2992 r->d()->context()->state.textBaseline = tb;
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007QV4::ReturnedValue
QQuickJSContext2DPrototype::method_fillText(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3009 QV4::Scope scope(b);
3010 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3014 qreal x = argv[1].toNumber();
3015 qreal y = argv[2].toNumber();
3016 if (!qt_is_finite(x) || !qt_is_finite(y))
3018 QPainterPath textPath = r->d()->context()->createTextGlyphs(x, y, argv[0].toQStringNoThrow());
3019 r->d()->context()->buffer()->fill(textPath);
3022 RETURN_RESULT(*thisObject);
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034QV4::ReturnedValue
QQuickJSContext2DPrototype::method_strokeText(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3036 QV4::Scope scope(b);
3037 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3041 r->d()->context()->drawText(argv[0].toQStringNoThrow(), argv[1].toNumber(), argv[2].toNumber(),
false);
3043 RETURN_RESULT(*thisObject);
3047
3048
3049
3050
3051
3052
3053QV4::ReturnedValue
QQuickJSContext2DPrototype::method_measureText(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3055 QV4::Scope scope(b);
3056 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3060 QFontMetrics fm(r->d()->context()->state.font);
3061 uint width = fm.horizontalAdvance(argv[0].toQStringNoThrow());
3062 QV4::ScopedObject tm(scope, scope.engine->newObject());
3063 tm->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral(
"width"))).getPointer(),
3064 QV4::ScopedValue(scope, QV4::Value::fromDouble(width)));
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129QV4::ReturnedValue
QQuickJSContext2DPrototype::method_drawImage(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3131 QV4::Scope scope(b);
3132 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3135 qreal sx, sy, sw, sh, dx, dy, dw, dh;
3141 if (!r->d()->context()->state.invertibleCTM)
3144 QQmlRefPointer<QQuickCanvasPixmap> pixmap;
3146 QV4::ScopedValue arg(scope, argv[0]);
3147 if (arg->isString()) {
3148 QUrl url(arg->toQString());
3150 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3152 pixmap = r->d()->context()->createPixmap(url);
3153 }
else if (arg->isObject()) {
3154 QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, arg);
3155 if (!!qobjectWrapper) {
3156 if (QQuickImage *imageItem = qobject_cast<QQuickImage*>(qobjectWrapper->object())) {
3157 pixmap = r->d()->context()->createPixmap(imageItem->source());
3158 }
else if (
QQuickCanvasItem *canvas = qobject_cast<QQuickCanvasItem*>(qobjectWrapper->object())) {
3159 QImage img = canvas->toImage();
3161 pixmap.adopt(
new QQuickCanvasPixmap(img));
3163 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3166 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, arg);
3168 QV4::Scoped<QQuickJSContext2DPixelData> pix(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3169 if (pix && !pix->d()->image->isNull()) {
3170 pixmap.adopt(
new QQuickCanvasPixmap(*pix->d()->image));
3172 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3175 QUrl url(arg->toQStringNoThrow());
3177 pixmap = r->d()->context()->createPixmap(url);
3179 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3183 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3186 if (pixmap.isNull() || !pixmap->isValid())
3190 sx = argv[1].toNumber();
3191 sy = argv[2].toNumber();
3192 sw = argv[3].toNumber();
3193 sh = argv[4].toNumber();
3194 dx = argv[5].toNumber();
3195 dy = argv[6].toNumber();
3196 dw = argv[7].toNumber();
3197 dh = argv[8].toNumber();
3198 }
else if (argc >= 5) {
3201 sw = pixmap->width();
3202 sh = pixmap->height();
3203 dx = argv[1].toNumber();
3204 dy = argv[2].toNumber();
3205 dw = argv[3].toNumber();
3206 dh = argv[4].toNumber();
3207 }
else if (argc >= 3) {
3208 dx = argv[1].toNumber();
3209 dy = argv[2].toNumber();
3212 sw = pixmap->width();
3213 sh = pixmap->height();
3220 if (!qt_is_finite(sx)
3221 || !qt_is_finite(sy)
3222 || !qt_is_finite(sw)
3223 || !qt_is_finite(sh)
3224 || !qt_is_finite(dx)
3225 || !qt_is_finite(dy)
3226 || !qt_is_finite(dw)
3227 || !qt_is_finite(dh))
3234 || sx + sw > pixmap->width()
3235 || sy + sh > pixmap->height()
3236 || sx + sw < 0 || sy + sh < 0) {
3237 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"drawImage(), index size error");
3240 r->d()->context()->buffer()->drawPixmap(pixmap, QRectF(sx, sy, sw, sh), QRectF(dx, dy, dw, dh));
3242 RETURN_RESULT(*thisObject);
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3266
3267
3268
3269QV4::ReturnedValue
QQuickJSContext2DImageData::method_get_width(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3271 QV4::Scope scope(b);
3272 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
3275 QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3276 int width = r ? r->d()->image->width() : 0;
3277 RETURN_RESULT(QV4::Encode(width));
3281
3282
3283
3284QV4::ReturnedValue
QQuickJSContext2DImageData::method_get_height(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3286 QV4::Scope scope(b);
3287 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
3290 QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3291 int height = r ? r->d()->image->height() : 0;
3292 RETURN_RESULT(QV4::Encode(height));
3296
3297
3298
3299QV4::ReturnedValue
QQuickJSContext2DImageData::method_get_data(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3301 QV4::Scope scope(b);
3302 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
3305 RETURN_RESULT(imageData->d()->pixelData);
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3321
3322
3323
3324
3325
3326QV4::ReturnedValue
QQuickJSContext2DPixelData::proto_get_length(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3328 QV4::Scope scope(b);
3329 QV4::Scoped<QQuickJSContext2DPixelData> r(scope, thisObject->as<QQuickJSContext2DPixelData>());
3330 if (!r || r->d()->image->isNull())
3333 RETURN_RESULT(QV4::Encode(r->d()->image->width() * r->d()->image->height() * 4));
3336QV4::ReturnedValue
QQuickJSContext2DPixelData::virtualGet(
const QV4::Managed *m, QV4::PropertyKey id,
const QV4::Value *receiver,
bool *hasProperty)
3338 if (!id.isArrayIndex())
3339 return QV4::Object::virtualGet(m, id, receiver, hasProperty);
3341 uint index = id.asArrayIndex();
3344 QV4::Scope scope(v4);
3345 QV4::Scoped<QQuickJSContext2DPixelData> r(scope,
static_cast<
const QQuickJSContext2DPixelData *>(m));
3347 if (index <
static_cast<quint32>(r->d()->image->width() * r->d()->image->height() * 4)) {
3349 *hasProperty =
true;
3350 const quint32 w = r->d()->image->width();
3351 const quint32 row = (index / 4) / w;
3352 const quint32 col = (index / 4) % w;
3353 const QRgb* pixel =
reinterpret_cast<
const QRgb*>(r->d()->image->constScanLine(row));
3355 switch (index % 4) {
3357 return QV4::Encode(qRed(*pixel));
3359 return QV4::Encode(qGreen(*pixel));
3361 return QV4::Encode(qBlue(*pixel));
3363 return QV4::Encode(qAlpha(*pixel));
3368 *hasProperty =
false;
3369 return QV4::Encode::undefined();
3372bool QQuickJSContext2DPixelData::virtualPut(QV4::Managed *m, QV4::PropertyKey id,
const QV4::Value &value, QV4::Value *receiver)
3374 if (!id.isArrayIndex())
3375 return Object::virtualPut(m, id, value, receiver);
3379 QV4::Scope scope(v4);
3380 if (scope.hasException())
3383 uint index = id.asArrayIndex();
3384 QV4::Scoped<QQuickJSContext2DPixelData> r(scope,
static_cast<QQuickJSContext2DPixelData *>(m));
3386 const int v = value.toInt32();
3387 if (r && index <
static_cast<quint32>(r->d()->image->width() * r->d()->image->height() * 4) && v >= 0 && v <= 255) {
3388 const quint32 w = r->d()->image->width();
3389 const quint32 row = (index / 4) / w;
3390 const quint32 col = (index / 4) % w;
3392 QRgb* pixel =
reinterpret_cast<QRgb*>(r->d()->image->scanLine(row));
3394 switch (index % 4) {
3396 *pixel = qRgba(v, qGreen(*pixel), qBlue(*pixel), qAlpha(*pixel));
3399 *pixel = qRgba(qRed(*pixel), v, qBlue(*pixel), qAlpha(*pixel));
3402 *pixel = qRgba(qRed(*pixel), qGreen(*pixel), v, qAlpha(*pixel));
3405 *pixel = qRgba(qRed(*pixel), qGreen(*pixel), qBlue(*pixel), v);
3414
3415
3416
3417
3419
3420
3421
3422
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createImageData(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3436 QV4::Scope scope(b);
3437 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
3441 QV4::ScopedValue arg0(scope, argv[0]);
3442 QV4::Scoped<QQuickJSContext2DImageData> imgData(scope, arg0);
3444 QV4::Scoped<QQuickJSContext2DPixelData> pa(scope, imgData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3446 qreal w = pa->d()->image->width();
3447 qreal h = pa->d()->image->height();
3448 RETURN_RESULT(qt_create_image_data(w, h, scope.engine, QImage()));
3450 }
else if (arg0->isString()) {
3451 QImage image = r->d()->context()->createPixmap(QUrl(arg0->toQStringNoThrow()))->image();
3452 RETURN_RESULT(qt_create_image_data(image.width(), image.height(), scope.engine, std::move(image)));
3454 }
else if (argc == 2) {
3455 qreal w = argv[0].toNumber();
3456 qreal h = argv[1].toNumber();
3458 if (!qt_is_finite(w) || !qt_is_finite(h))
3459 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createImageData(): invalid arguments");
3462 RETURN_RESULT(qt_create_image_data(w, h, scope.engine, QImage()));
3464 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"createImageData(): invalid arguments");
3470
3471
3472
3473
3474
3475QV4::ReturnedValue
QQuickJSContext2DPrototype::method_getImageData(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3477 QV4::Scope scope(b);
3478 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
3482 qreal x = argv[0].toNumber();
3483 qreal y = argv[1].toNumber();
3484 qreal w = argv[2].toNumber();
3485 qreal h = argv[3].toNumber();
3486 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3487 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"getImageData(): Invalid arguments");
3489 if (w <= 0 || h <= 0)
3490 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"getImageData(): Invalid arguments");
3492 QImage image = r->d()->context()->canvas()->toImage(QRectF(x, y, w, h));
3493 RETURN_RESULT(qt_create_image_data(w, h, scope.engine, std::move(image)));
3495 RETURN_RESULT(QV4::Encode::null());
3499
3500
3501
3502
3503
3504
3505
3506
3507QV4::ReturnedValue
QQuickJSContext2DPrototype::method_putImageData(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3509 QV4::Scope scope(b);
3510 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
3515 QV4::ScopedValue arg0(scope, argv[0]);
3516 if (!arg0->isObject())
3517 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"Context2D::putImageData, the image data type mismatch");
3519 qreal dx = argv[1].toNumber();
3520 qreal dy = argv[2].toNumber();
3521 qreal w, h, dirtyX, dirtyY, dirtyWidth, dirtyHeight;
3523 if (!qt_is_finite(dx) || !qt_is_finite(dy))
3524 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"putImageData() : Invalid arguments");
3526 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, arg0);
3530 QV4::Scoped<QQuickJSContext2DPixelData> pixelArray(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3532 w = pixelArray->d()->image->width();
3533 h = pixelArray->d()->image->height();
3536 dirtyX = argv[3].toNumber();
3537 dirtyY = argv[4].toNumber();
3538 dirtyWidth = argv[5].toNumber();
3539 dirtyHeight = argv[6].toNumber();
3541 if (!qt_is_finite(dirtyX) || !qt_is_finite(dirtyY) || !qt_is_finite(dirtyWidth) || !qt_is_finite(dirtyHeight))
3542 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"putImageData() : Invalid arguments");
3545 if (dirtyWidth < 0) {
3546 dirtyX = dirtyX+dirtyWidth;
3547 dirtyWidth = -dirtyWidth;
3550 if (dirtyHeight < 0) {
3551 dirtyY = dirtyY+dirtyHeight;
3552 dirtyHeight = -dirtyHeight;
3556 dirtyWidth = dirtyWidth+dirtyX;
3561 dirtyHeight = dirtyHeight+dirtyY;
3565 if (dirtyX+dirtyWidth > w) {
3566 dirtyWidth = w - dirtyX;
3569 if (dirtyY+dirtyHeight > h) {
3570 dirtyHeight = h - dirtyY;
3573 if (dirtyWidth <=0 || dirtyHeight <= 0)
3582 QImage image = pixelArray->d()->image->copy(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
3583 r->d()->context()->buffer()->drawImage(image, QRectF(dirtyX, dirtyY, dirtyWidth, dirtyHeight), QRectF(dx, dy, dirtyWidth, dirtyHeight));
3586 RETURN_RESULT(*thisObject);
3590
3591
3592
3593
3594
3595
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611QV4::ReturnedValue
QQuickContext2DStyle::gradient_proto_addColorStop(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3613 QV4::Scope scope(b);
3614 QV4::Scoped<QQuickContext2DStyle> style(scope, thisObject->as<QQuickContext2DStyle>());
3616 THROW_GENERIC_ERROR(
"Not a CanvasGradient object");
3620 if (!style->d()->brush->gradient())
3621 THROW_GENERIC_ERROR(
"Not a valid CanvasGradient object, can't get the gradient information");
3622 QGradient gradient = *(style->d()->brush->gradient());
3623 qreal pos = argv[0].toNumber();
3626 if (argv[1].as<Object>()) {
3627 color = QV4::ExecutionEngine::toVariant(
3628 argv[1], QMetaType::fromType<QColor>()).value<QColor>();
3630 color = qt_color_from_string(argv[1]);
3632 if (pos < 0.0 || pos > 1.0 || !qt_is_finite(pos)) {
3633 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"CanvasGradient: parameter offset out of range");
3636 if (color.isValid()) {
3637 gradient.setColorAt(pos, color);
3639 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"CanvasGradient: parameter color is not a valid color string");
3641 *style->d()->brush = gradient;
3644 return thisObject->asReturnedValue();
3649 if (!state.invertibleCTM)
3652 if (!qt_is_finite(x) || !qt_is_finite(y))
3655 QTransform newTransform = state.matrix;
3656 newTransform.scale(x, y);
3658 if (!newTransform.isInvertible()) {
3659 state.invertibleCTM =
false;
3663 state.matrix = newTransform;
3664 buffer()->updateMatrix(state.matrix);
3665 m_path = QTransform().scale(1.0 / x, 1.0 / y).map(m_path);
3670 if (!state.invertibleCTM)
3673 if (!qt_is_finite(angle))
3676 QTransform newTransform =state.matrix;
3677 newTransform.rotate(qRadiansToDegrees(angle));
3679 if (!newTransform.isInvertible()) {
3680 state.invertibleCTM =
false;
3684 state.matrix = newTransform;
3685 buffer()->updateMatrix(state.matrix);
3686 m_path = QTransform().rotate(-qRadiansToDegrees(angle)).map(m_path);
3691 if (!state.invertibleCTM)
3694 if (!qt_is_finite(h) || !qt_is_finite(v))
3697 QTransform newTransform = state.matrix;
3698 newTransform.shear(h, v);
3700 if (!newTransform.isInvertible()) {
3701 state.invertibleCTM =
false;
3705 state.matrix = newTransform;
3706 buffer()->updateMatrix(state.matrix);
3707 m_path = QTransform().shear(-h, -v).map(m_path);
3712 if (!state.invertibleCTM)
3715 if (!qt_is_finite(x) || !qt_is_finite(y))
3718 QTransform newTransform = state.matrix;
3719 newTransform.translate(x, y);
3721 if (!newTransform.isInvertible()) {
3722 state.invertibleCTM =
false;
3726 state.matrix = newTransform;
3727 buffer()->updateMatrix(state.matrix);
3728 m_path = QTransform().translate(-x, -y).map(m_path);
3733 if (!state.invertibleCTM)
3736 if (!qt_is_finite(a) || !qt_is_finite(b) || !qt_is_finite(c) || !qt_is_finite(d) || !qt_is_finite(e) || !qt_is_finite(f))
3739 QTransform transform(a, b, c, d, e, f);
3740 QTransform newTransform = state.matrix * transform;
3742 if (!newTransform.isInvertible()) {
3743 state.invertibleCTM =
false;
3746 state.matrix = newTransform;
3747 buffer()->updateMatrix(state.matrix);
3748 m_path = transform.inverted().map(m_path);
3753 if (!qt_is_finite(a) || !qt_is_finite(b) || !qt_is_finite(c) || !qt_is_finite(d) || !qt_is_finite(e) || !qt_is_finite(f))
3756 QTransform ctm = state.matrix;
3757 if (!ctm.isInvertible())
3760 state.matrix = ctm.inverted() * state.matrix;
3761 m_path = ctm.map(m_path);
3762 state.invertibleCTM =
true;
3763 transform(a, b, c, d, e, f);
3768 if (!state.invertibleCTM)
3771 if (!m_path.elementCount())
3774 m_path.setFillRule(state.fillRule);
3775 buffer()->fill(m_path);
3780 if (!state.invertibleCTM)
3783 QPainterPath clipPath = m_path;
3784 clipPath.closeSubpath();
3786 state.clipPath = clipPath.intersected(state.clipPath);
3789 state.clipPath = clipPath;
3791 buffer()->clip(state.clip, state.clipPath);
3796 if (!state.invertibleCTM)
3799 if (!m_path.elementCount())
3802 buffer()->stroke(m_path);
3807 if (!state.invertibleCTM)
3810 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3813 buffer()->fillRect(QRectF(x, y, w, h));
3818 if (!state.invertibleCTM)
3821 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3824 buffer()->strokeRect(QRectF(x, y, w, h));
3829 if (!state.invertibleCTM)
3832 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3835 buffer()->clearRect(QRectF(x, y, w, h));
3840 if (!state.invertibleCTM)
3843 if (!qt_is_finite(x) || !qt_is_finite(y))
3846 QPainterPath textPath = createTextGlyphs(x, y, text);
3856 if (!m_path.elementCount())
3858 m_path = QPainterPath();
3863 if (!m_path.elementCount())
3866 QRectF boundRect = m_path.boundingRect();
3867 if (boundRect.width() || boundRect.height())
3868 m_path.closeSubpath();
3875 if (!state.invertibleCTM)
3879 m_path.moveTo(QPointF(x, y));
3884 if (!state.invertibleCTM)
3889 if (!m_path.elementCount())
3891 else if (m_path.currentPosition() != pt)
3898 if (!state.invertibleCTM)
3901 if (!m_path.elementCount())
3902 m_path.moveTo(QPointF(cpx, cpy));
3905 if (m_path.currentPosition() != pt)
3906 m_path.quadTo(QPointF(cpx, cpy), pt);
3910 qreal cp2x, qreal cp2y,
3913 if (!state.invertibleCTM)
3916 if (!m_path.elementCount())
3917 m_path.moveTo(QPointF(cp1x, cp1y));
3920 if (m_path.currentPosition() != pt)
3921 m_path.cubicTo(QPointF(cp1x, cp1y), QPointF(cp2x, cp2y), pt);
3926 QPointF p0(m_path.currentPosition());
3928 QPointF p1p0((p0.x() - p1.x()), (p0.y() - p1.y()));
3929 QPointF p1p2((p2.x() - p1.x()), (p2.y() - p1.y()));
3930 qreal p1p0_length =
std::hypot(p1p0.x(), p1p0.y());
3931 qreal p1p2_length =
std::hypot(p1p2.x(), p1p2.y());
3933 qreal cos_phi = QPointF::dotProduct(p1p0, p1p2) / (p1p0_length * p1p2_length);
3938 if (qFuzzyCompare(
std::abs(cos_phi), qreal(1.0))) {
3943 qreal tangent = radius /
std::tan(
std::acos(cos_phi) / 2);
3944 qreal factor_p1p0 = tangent / p1p0_length;
3945 QPointF t_p1p0((p1.x() + factor_p1p0 * p1p0.x()), (p1.y() + factor_p1p0 * p1p0.y()));
3947 QPointF orth_p1p0(p1p0.y(), -p1p0.x());
3948 qreal orth_p1p0_length =
std::hypot(orth_p1p0.x(), orth_p1p0.y());
3949 qreal factor_ra = radius / orth_p1p0_length;
3952 qreal cos_alpha = QPointF::dotProduct(orth_p1p0, p1p2) / (orth_p1p0_length * p1p2_length);
3953 if (cos_alpha < 0.f)
3954 orth_p1p0 = QPointF(-orth_p1p0.x(), -orth_p1p0.y());
3956 QPointF p((t_p1p0.x() + factor_ra * orth_p1p0.x()), (t_p1p0.y() + factor_ra * orth_p1p0.y()));
3959 orth_p1p0 = QPointF(-orth_p1p0.x(), -orth_p1p0.y());
3960 qreal sa =
std::atan2(orth_p1p0.y(), orth_p1p0.x());
3963 bool anticlockwise =
false;
3965 qreal factor_p1p2 = tangent / p1p2_length;
3966 QPointF t_p1p2((p1.x() + factor_p1p2 * p1p2.x()), (p1.y() + factor_p1p2 * p1p2.y()));
3967 QPointF orth_p1p2((t_p1p2.x() - p.x()), (t_p1p2.y() - p.y()));
3968 qreal ea =
std::atan2(orth_p1p2.y(), orth_p1p2.x());
3969 if ((sa > ea) && ((sa - ea) <
M_PI))
3970 anticlockwise =
true;
3971 if ((sa < ea) && ((ea - sa) >
M_PI))
3972 anticlockwise =
true;
3974 arc(p.x(), p.y(), radius, sa, ea, anticlockwise);
3981 if (!state.invertibleCTM)
3984 if (!qt_is_finite(x1) || !qt_is_finite(y1) || !qt_is_finite(x2) || !qt_is_finite(y2) || !qt_is_finite(radius))
3988 QPointF end(x2, y2);
3990 if (!m_path.elementCount())
3992 else if (st == m_path.currentPosition() || st == end || !radius)
3995 addArcTo(st, end, radius);
4000 if (!state.invertibleCTM)
4002 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
4006 m_path.moveTo(x, y);
4009 m_path.addRect(x, y, w, h);
4016 if (!state.invertibleCTM)
4019 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h) || !qt_is_finite(xr) || !qt_is_finite(yr))
4023 m_path.moveTo(x, y);
4026 m_path.addRoundedRect(QRectF(x, y, w, h), xr, yr, Qt::AbsoluteSize);
4032 if (!state.invertibleCTM)
4035 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
4039 m_path.moveTo(x, y);
4043 m_path.addEllipse(x, y, w, h);
4048 if (!state.invertibleCTM)
4052 path.addText(x, y, state.font, str);
4053 m_path.addPath(path);
4058 if (!state.invertibleCTM)
4061 if (!qt_is_finite(xc) || !qt_is_finite(yc) || !qt_is_finite(sar) || !qt_is_finite(ear) || !qt_is_finite(radius))
4075 antiClockWise = !antiClockWise;
4078 float sa = qRadiansToDegrees(sar);
4079 float ea = qRadiansToDegrees(ear);
4083 double xs = xc - radius;
4084 double ys = yc - radius;
4085 double width = radius*2;
4086 double height = radius*2;
4087 if ((!antiClockWise && (ea - sa >= 360)) || (antiClockWise && (sa - ea >= 360)))
4093 if (!antiClockWise && (ea < sa)) {
4095 }
else if (antiClockWise && (sa < ea)) {
4100 if (!(qFuzzyCompare(span + (ea - sa) + 1, 1) &&
4101 qFuzzyCompare(qAbs(span), 360))) {
4107 if (!m_path.elementCount())
4108 m_path.arcMoveTo(xs, ys, width, height, sa);
4110 m_path.lineTo(xc, yc);
4114 m_path.arcTo(xs, ys, width, height, sa, span);
4117int baseLineOffset(QQuickContext2D::TextBaseLineType value,
const QFontMetrics &metrics)
4121 case QQuickContext2D::Top:
4122 case QQuickContext2D::Hanging:
4124 case QQuickContext2D::Middle:
4125 offset = (metrics.ascent() >> 1) + metrics.height() - metrics.ascent();
4127 case QQuickContext2D::Alphabetic:
4128 offset = metrics.ascent();
4130 case QQuickContext2D::Bottom:
4131 offset = metrics.height();
4140 if (value == QQuickContext2D::Start)
4141 value = QGuiApplication::layoutDirection() == Qt::LeftToRight ? QQuickContext2D::Left : QQuickContext2D::Right;
4142 else if (value == QQuickContext2D::End)
4143 value = QGuiApplication::layoutDirection() == Qt::LeftToRight ? QQuickContext2D::Right: QQuickContext2D::Left;
4146 offset = metrics.horizontalAdvance(text) / 2;
4149 offset = metrics.horizontalAdvance(text);
4160 m_grabbedImage = grab;
4164QQmlRefPointer<QQuickCanvasPixmap>
QQuickContext2D::createPixmap(
const QUrl& url, QSizeF sourceSize)
4166 return m_canvas->loadedPixmap(url, sourceSize);
4171 const QFontMetrics metrics(state.font);
4172 int yoffset = baseLineOffset(
static_cast<QQuickContext2D::TextBaseLineType>(state.textBaseline), metrics);
4173 int xoffset = textAlignOffset(
static_cast<QQuickContext2D::TextAlignType>(state.textAlign), metrics, text);
4175 QPainterPath textPath;
4177 textPath.addText(x - xoffset, y - yoffset+metrics.ascent(), state.font, text);
4182static inline bool areCollinear(
const QPointF& a,
const QPointF& b,
const QPointF& c)
4185 return qFuzzyCompare((c.y() - b.y()) * (a.x() - b.x()), (a.y() - b.y()) * (c.x() - b.x()));
4190 return (p >= a && p <= b) || (p >= b && p <= a);
4195 if (!state.invertibleCTM)
4198 if (!m_path.elementCount())
4201 if (!qt_is_finite(x) || !qt_is_finite(y))
4204 QPointF point(x, y);
4205 QTransform ctm = state.matrix;
4206 QPointF p = ctm.inverted().map(point);
4207 if (!qt_is_finite(p.x()) || !qt_is_finite(p.y()))
4210 const_cast<QQuickContext2D *>(
this)->m_path.setFillRule(state.fillRule);
4212 bool contains = m_path.contains(p);
4216 QPolygonF border = m_path.toFillPolygon();
4218 QPointF p1 = border.at(0);
4221 for (
int i = 1; i < border.size(); ++i) {
4223 if (areCollinear(p, p1, p2)
4226 && (qAbs(p2.x() - p1.x()) > qAbs(p2.y() - p1.y()) ?
4227 withinRange(p.x(), p1.x(), p2.x()) :
4228 withinRange(p.y(), p1.y(), p2.y()))) {
4261 return m_v4value.value();
4266 return QStringList() << QStringLiteral(
"2d");
4273 m_canvas = canvasItem;
4274 m_renderTarget = canvasItem->renderTarget();
4275 m_renderStrategy = canvasItem->renderStrategy();
4278 if (m_renderTarget == QQuickCanvasItem::FramebufferObject
4279 && m_renderStrategy == QQuickCanvasItem::Threaded
4280 && !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL)) {
4281 m_renderTarget = QQuickCanvasItem::Image;
4287 if (m_renderTarget == QQuickCanvasItem::FramebufferObject)
4288 m_renderTarget = QQuickCanvasItem::Image;
4290 m_texture =
new QQuickContext2DImageTexture;
4293 m_texture->setCanvasWindow(canvasItem->canvasWindow().toRect());
4294 m_texture->setTileSize(canvasItem->tileSize());
4295 m_texture->setCanvasSize(canvasItem->canvasSize().toSize());
4296 m_texture->setSmooth(canvasItem->smooth());
4297 m_texture->setAntialiasing(canvasItem->antialiasing());
4298 m_texture->setOnCustomThread(m_renderStrategy == QQuickCanvasItem::Threaded);
4299 m_thread = QThread::currentThread();
4301 QThread *renderThread = m_thread;
4302 if (m_renderStrategy == QQuickCanvasItem::Threaded)
4304 if (renderThread && renderThread != QThread::currentThread())
4306 connect(
m_texture, SIGNAL(textureChanged()), SIGNAL(textureChanged()));
4311void QQuickContext2D::
prepare(
const QSize& canvasSize,
const QSize& tileSize,
const QRect& canvasWindow,
const QRect& dirtyRect,
bool smooth,
bool antialiasing)
4313 if (m_texture->thread() == QThread::currentThread()) {
4314 m_texture->canvasChanged(canvasSize, tileSize, canvasWindow, dirtyRect, smooth, antialiasing);
4316 QEvent *e =
new QQuickContext2DTexture::CanvasChangeEvent(canvasSize,
4322 QCoreApplication::postEvent(m_texture, e);
4329 if (m_texture->thread() == QThread::currentThread())
4332 QCoreApplication::postEvent(m_texture,
new QQuickContext2DTexture::PaintEvent(m_buffer));
4344 if (m_texture->thread() == QThread::currentThread()) {
4347 }
else if (m_renderStrategy == QQuickCanvasItem::Cooperative) {
4348 qWarning() <<
"Pixel readback is not supported in Cooperative mode, please try Threaded or Immediate mode";
4352 QCoreApplication::postEvent(m_texture,
new QEvent(QEvent::Type(QEvent::User + 10)));
4353 QMetaObject::invokeMethod(m_texture,
4355 Qt::BlockingQueuedConnection,
4356 Q_ARG(QRectF, bounds));
4358 QImage img = m_grabbedImage;
4359 m_grabbedImage = QImage();
4367 QV4::Scope scope(v4);
4369 QV4::ScopedObject proto(scope, QQuickJSContext2DPrototype::create(v4));
4370 proto->defineAccessorProperty(QStringLiteral(
"strokeStyle"), QQuickJSContext2D::method_get_strokeStyle, QQuickJSContext2D::method_set_strokeStyle);
4371 proto->defineAccessorProperty(QStringLiteral(
"font"), QQuickJSContext2D::method_get_font, QQuickJSContext2D::method_set_font);
4372 proto->defineAccessorProperty(QStringLiteral(
"fillRule"), QQuickJSContext2D::method_get_fillRule, QQuickJSContext2D::method_set_fillRule);
4373 proto->defineAccessorProperty(QStringLiteral(
"globalAlpha"), QQuickJSContext2D::method_get_globalAlpha, QQuickJSContext2D::method_set_globalAlpha);
4374 proto->defineAccessorProperty(QStringLiteral(
"lineCap"), QQuickJSContext2D::method_get_lineCap, QQuickJSContext2D::method_set_lineCap);
4375 proto->defineAccessorProperty(QStringLiteral(
"shadowOffsetX"), QQuickJSContext2D::method_get_shadowOffsetX, QQuickJSContext2D::method_set_shadowOffsetX);
4376 proto->defineAccessorProperty(QStringLiteral(
"shadowOffsetY"), QQuickJSContext2D::method_get_shadowOffsetY, QQuickJSContext2D::method_set_shadowOffsetY);
4377 proto->defineAccessorProperty(QStringLiteral(
"globalCompositeOperation"), QQuickJSContext2D::method_get_globalCompositeOperation, QQuickJSContext2D::method_set_globalCompositeOperation);
4378 proto->defineAccessorProperty(QStringLiteral(
"miterLimit"), QQuickJSContext2D::method_get_miterLimit, QQuickJSContext2D::method_set_miterLimit);
4379 proto->defineAccessorProperty(QStringLiteral(
"fillStyle"), QQuickJSContext2D::method_get_fillStyle, QQuickJSContext2D::method_set_fillStyle);
4380 proto->defineAccessorProperty(QStringLiteral(
"shadowColor"), QQuickJSContext2D::method_get_shadowColor, QQuickJSContext2D::method_set_shadowColor);
4381 proto->defineAccessorProperty(QStringLiteral(
"textBaseline"), QQuickJSContext2D::method_get_textBaseline, QQuickJSContext2D::method_set_textBaseline);
4382#if QT_CONFIG(quick_path)
4383 proto->defineAccessorProperty(QStringLiteral(
"path"), QQuickJSContext2D::method_get_path, QQuickJSContext2D::method_set_path);
4385 proto->defineAccessorProperty(QStringLiteral(
"lineJoin"), QQuickJSContext2D::method_get_lineJoin, QQuickJSContext2D::method_set_lineJoin);
4386 proto->defineAccessorProperty(QStringLiteral(
"lineWidth"), QQuickJSContext2D::method_get_lineWidth, QQuickJSContext2D::method_set_lineWidth);
4387 proto->defineAccessorProperty(QStringLiteral(
"textAlign"), QQuickJSContext2D::method_get_textAlign, QQuickJSContext2D::method_set_textAlign);
4388 proto->defineAccessorProperty(QStringLiteral(
"shadowBlur"), QQuickJSContext2D::method_get_shadowBlur, QQuickJSContext2D::method_set_shadowBlur);
4389 proto->defineAccessorProperty(QStringLiteral(
"lineDashOffset"), QQuickJSContext2D::method_get_lineDashOffset, QQuickJSContext2D::method_set_lineDashOffset);
4390 contextPrototype = proto;
4392 proto = scope.engine->newObject();
4393 proto->defineDefaultProperty(QStringLiteral(
"addColorStop"), QQuickContext2DStyle::gradient_proto_addColorStop, 0);
4394 gradientProto = proto;
4396 proto = scope.engine->newObject();
4397 proto->defineAccessorProperty(scope.engine->id_length(), QQuickJSContext2DPixelData::proto_get_length,
nullptr);
4398 pixelArrayProto = proto;
4407 if (m_stateStack.isEmpty())
4412 if (state.matrix != newState.matrix)
4413 buffer()->updateMatrix(newState.matrix);
4415 if (newState.globalAlpha != state.globalAlpha)
4416 buffer()->setGlobalAlpha(newState.globalAlpha);
4418 if (newState.globalCompositeOperation != state.globalCompositeOperation)
4419 buffer()->setGlobalCompositeOperation(newState.globalCompositeOperation);
4421 if (newState.fillStyle != state.fillStyle)
4422 buffer()->setFillStyle(newState.fillStyle);
4424 if (newState.strokeStyle != state.strokeStyle)
4425 buffer()->setStrokeStyle(newState.strokeStyle);
4427 if (newState.lineWidth != state.lineWidth)
4428 buffer()->setLineWidth(newState.lineWidth);
4430 if (newState.lineCap != state.lineCap)
4431 buffer()->setLineCap(newState.lineCap);
4433 if (newState.lineJoin != state.lineJoin)
4434 buffer()->setLineJoin(newState.lineJoin);
4436 if (newState.miterLimit != state.miterLimit)
4437 buffer()->setMiterLimit(newState.miterLimit);
4439 if (newState.clip != state.clip || newState.clipPath != state.clipPath)
4442 if (newState.shadowBlur != state.shadowBlur)
4443 buffer()->setShadowBlur(newState.shadowBlur);
4445 if (newState.shadowColor != state.shadowColor)
4446 buffer()->setShadowColor(newState.shadowColor);
4448 if (newState.shadowOffsetX != state.shadowOffsetX)
4449 buffer()->setShadowOffsetX(newState.shadowOffsetX);
4451 if (newState.shadowOffsetY != state.shadowOffsetY)
4452 buffer()->setShadowOffsetY(newState.shadowOffsetY);
4454 if (newState.lineDash != state.lineDash)
4455 buffer()->setLineDash(newState.lineDash);
4457 m_path = state.matrix.map(m_path);
4459 m_path = state.matrix.inverted().map(m_path);
4463 m_stateStack.push(state);
4470 m_path = QPainterPath();
4472 newState.clipPath.setFillRule(Qt::WindingFill);
4474 m_stateStack.clear();
4475 m_stateStack.push(newState);
4477 m_buffer->clearRect(QRectF(0, 0, m_canvas->width(), m_canvas->height()));
4494 QV4::Scope scope(engine);
4495 QV4::Scoped<QQuickJSContext2D> wrapper(scope, engine->memoryManager->allocate<QQuickJSContext2D>());
4496 QV4::ScopedObject p(scope, ed->contextPrototype.value());
4497 wrapper->setPrototypeOf(p);
4498 wrapper->d()->setContext(
this);
4499 m_v4value = wrapper;
4505#include "moc_qquickcontext2d_p.cpp"
QQuickContext2DCommandBuffer()
QV4::PersistentValue gradientProto
~QQuickContext2DEngineData()
QQuickContext2DEngineData(QV4::ExecutionEngine *engine)
QV4::PersistentValue contextPrototype
QV4::PersistentValue pixelArrayProto
static QQuickContext2DRenderThread * instance(QQmlEngine *engine)
QPainterPath createTextGlyphs(qreal x, qreal y, const QString &text)
bool isPointInPath(qreal x, qreal y) const
void arcTo(qreal x1, qreal y1, qreal x2, qreal y2, qreal radius)
void translate(qreal x, qreal y)
QQuickContext2DTexture * texture() const
QV4::ExecutionEngine * v4Engine() const override
void strokeRect(qreal x, qreal y, qreal w, qreal h)
void text(const QString &str, qreal x, qreal y)
void ellipse(qreal x, qreal y, qreal w, qreal h)
QV4::ExecutionEngine * m_v4engine
QV4::ReturnedValue v4value() const override
void setTransform(qreal a, qreal b, qreal c, qreal d, qreal e, qreal f)
QImage toImage(const QRectF &bounds) override
void arc(qreal x, qreal y, qreal radius, qreal startAngle, qreal endAngle, bool anticlockwise)
QStringList contextNames() const override
void setGrabbedImage(const QImage &grab)
void lineTo(qreal x, qreal y)
QQuickContext2D(QObject *parent=nullptr)
QQuickContext2DCommandBuffer * buffer() const
void scale(qreal x, qreal y)
void bezierCurveTo(qreal cp1x, qreal cp1y, qreal cp2x, qreal cp2y, qreal x, qreal y)
void prepare(const QSize &canvasSize, const QSize &tileSize, const QRect &canvasWindow, const QRect &dirtyRect, bool smooth, bool antialiasing) override
QQuickContext2DTexture * m_texture
void quadraticCurveTo(qreal cpx, qreal cpy, qreal x, qreal y)
void drawText(const QString &text, qreal x, qreal y, bool fill)
void roundedRect(qreal x, qreal y, qreal w, qreal h, qreal xr, qreal yr)
void setV4Engine(QV4::ExecutionEngine *eng) override
void shear(qreal h, qreal v)
QQuickContext2DCommandBuffer * m_buffer
void clearRect(qreal x, qreal y, qreal w, qreal h)
void addArcTo(const QPointF &p1, const QPointF &p2, qreal radius)
void transform(qreal a, qreal b, qreal c, qreal d, qreal e, qreal f)
void rect(qreal x, qreal y, qreal w, qreal h)
void moveTo(qreal x, qreal y)
void fillRect(qreal x, qreal y, qreal w, qreal h)
static bool withinRange(qreal p, qreal a, qreal b)
#define qClamp(val, min, max)
static QPainter::CompositionMode qt_composite_mode_from_string(const QString &compositeOperator)
DEFINE_OBJECT_VTABLE(QQuickJSContext2DPrototype)
static QFont qt_font_from_string(const QString &fontString, const QFont ¤tFont)
DEFINE_OBJECT_VTABLE(QQuickContext2DStyle)
QImage qt_image_convolute_filter(const QImage &src, const QVector< qreal > &weights, int radius=0)
static int textAlignOffset(QQuickContext2D::TextAlignType value, const QFontMetrics &metrics, const QString &text)
#define CHECK_CONTEXT(r)
\qmltype Context2D \nativetype QQuickContext2D \inqmlmodule QtQuick
#define Q_TRY_SET_TOKEN(token, value, setStatement)
int baseLineOffset(QQuickContext2D::TextBaseLineType value, const QFontMetrics &metrics)
void qt_image_boxblur(QImage &image, int radius, bool quality)
static bool qSetFontFamilyFromTokens(QFont &font, const QStringList &fontFamilyTokens)
DEFINE_OBJECT_VTABLE(QQuickJSContext2DImageData)
static bool areCollinear(const QPointF &a, const QPointF &b, const QPointF &c)
#define CHECK_CONTEXT_SETTER(r)
static bool qSetFontSizeFromToken(QFont &font, QStringView fontSizeToken)
static int qParseFontSizeFromToken(QStringView fontSizeToken, bool &ok)
static QV4::ReturnedValue qt_create_image_data(qreal w, qreal h, QV4::ExecutionEngine *v4, QImage &&image)
DEFINE_OBJECT_VTABLE(QQuickJSContext2DPixelData)
static QString qt_composite_mode_to_string(QPainter::CompositionMode op)
static QStringList qExtractFontFamiliesFromString(QStringView fontFamiliesString)
DEFINE_OBJECT_VTABLE(QQuickJSContext2D)
QDebug Q_QUICK_EXPORT operator<<(QDebug debug, const QQuickWindow *item)
static QV4::ReturnedValue method_get_data(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty object QtQuick::CanvasImageData::data Holds the one-dimensional array containing the dat...
static QV4::ReturnedValue method_get_height(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty int QtQuick::CanvasImageData::height Holds the actual height dimension of the data in th...
static bool virtualPut(QV4::Managed *m, QV4::PropertyKey id, const QV4::Value &value, Value *receiver)
static QV4::ReturnedValue proto_get_length(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmltype CanvasPixelArray \inqmlmodule QtQuick
static QV4::ReturnedValue method_isPointInPath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::isPointInPath(real x, real y)
static QV4::ReturnedValue method_measureText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::measureText(text)
static QV4::ReturnedValue method_moveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::moveTo(real x, real y)
static QV4::ReturnedValue method_bezierCurveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::bezierCurveTo(real cp1x, real cp1y, real cp2x,...
static QV4::ReturnedValue method_getImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod CanvasImageData QtQuick::Context2D::getImageData(real x, real y, real w,...
static QV4::ReturnedValue method_setLineDash(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod QtQuick::Context2D::setLineDash(array pattern)
static QV4::ReturnedValue method_quadraticCurveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::quadraticCurveTo(real cpx, real cpy, real x,...
static QV4::ReturnedValue method_drawImage(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod QtQuick::Context2D::drawImage(variant image, real dx, real dy) Draws the given image on th...
static QV4::ReturnedValue method_scale(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::scale(real x, real y)
static QV4::ReturnedValue method_stroke(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::stroke()
static QV4::ReturnedValue method_closePath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::closePath() Closes the current subpath by drawing a line to the...
static QV4::ReturnedValue method_strokeRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::strokeRect(real x, real y, real w, real h)
static QV4::ReturnedValue method_transform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::transform(real a, real b, real c, real d, real e,...
static QV4::ReturnedValue method_translate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::translate(real x, real y)
static QV4::ReturnedValue method_ellipse(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::ellipse(real x, real y, real w, real h)
static QV4::ReturnedValue method_resetTransform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::resetTransform()
static QV4::ReturnedValue method_createRadialGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::createRadialGradient(real x0, real y0, real r0,...
static QV4::ReturnedValue method_clip(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::clip()
static QV4::ReturnedValue method_createLinearGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::createLinearGradient(real x0, real y0, real x1,...
static QV4::ReturnedValue method_reset(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::reset() Resets the context state and properties to the default ...
static QV4::ReturnedValue method_fillText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::fillText(text, x, y)
static QV4::ReturnedValue method_arc(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::arc(real x, real y, real radius, real startAngle,...
static QV4::ReturnedValue method_save(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::save() Pushes the current state onto the state stack.
static QV4::ReturnedValue method_drawFocusRing(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_shear(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::shear(real sh, real sv)
static QV4::ReturnedValue method_lineTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::lineTo(real x, real y)
static QV4::ReturnedValue method_setTransform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::setTransform(real a, real b, real c, real d,...
static QV4::ReturnedValue method_createConicalGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::createConicalGradient(real x, real y, real angle)
static QV4::ReturnedValue method_strokeText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::strokeText(text, x, y)
static QV4::ReturnedValue method_restore(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::restore() Pops the top state on the stack, restoring the contex...
static QV4::ReturnedValue method_rect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::rect(real x, real y, real w, real h)
static QV4::ReturnedValue method_beginPath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::beginPath()
static QV4::ReturnedValue method_rotate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::rotate(real angle) Rotate the canvas around the current origin ...
static QV4::ReturnedValue method_fillRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::fillRect(real x, real y, real w, real h)
static QV4::ReturnedValue method_getLineDash(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod array QtQuick::Context2D::getLineDash()
static QV4::ReturnedValue method_arcTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::arcTo(real x1, real y1, real x2, real y2,...
static QV4::ReturnedValue method_fill(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::fill()
static QV4::ReturnedValue method_setCaretSelectionRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_createImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod CanvasImageData QtQuick::Context2D::createImageData(real sw, real sh)
static QV4::ReturnedValue method_createPattern(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod variant QtQuick::Context2D::createPattern(color color, enumeration patternMode) This is an...
static QV4::ReturnedValue method_roundedRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::roundedRect(real x, real y, real w, real h, real xRadius,...
static QV4::ReturnedValue method_caretBlinkRate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_putImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::putImageData(CanvasImageData imageData, real dx,...
static QV4::ReturnedValue method_text(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::text(string text, real x, real y)
static QV4::ReturnedValue method_clearRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::clearRect(real x, real y, real w, real h)
static QV4::ReturnedValue method_set_miterLimit(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_fillRule(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_lineCap(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_textAlign(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_lineJoin(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::lineJoin Holds the current line join style.
static QV4::ReturnedValue method_get_globalCompositeOperation(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::globalCompositeOperation Holds the current the current compos...
static QV4::ReturnedValue method_set_shadowOffsetX(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_fillRule(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty enumeration QtQuick::Context2D::fillRule Holds the current fill rule used for filling sh...
static QV4::ReturnedValue method_set_strokeStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_lineCap(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::lineCap Holds the current line cap style.
static QV4::ReturnedValue method_set_font(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_lineDashOffset(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::lineDashOffset
static QV4::ReturnedValue method_get_textAlign(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::textAlign
static QV4::ReturnedValue method_set_globalAlpha(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_textBaseline(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_lineWidth(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::lineWidth Holds the current line width.
static QV4::ReturnedValue method_set_fillStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_shadowOffsetY(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_font(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::font Holds the current font settings.
static QV4::ReturnedValue method_get_fillStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty variant QtQuick::Context2D::fillStyle Holds the current style used for filling shapes.
static QV4::ReturnedValue method_get_shadowBlur(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::shadowBlur Holds the current level of blur applied to shadows
static QV4::ReturnedValue method_get_shadowOffsetY(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::shadowOffsetY Holds the current shadow offset in the positive v...
static QV4::ReturnedValue method_get_miterLimit(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::miterLimit Holds the current miter limit ratio.
static QV4::ReturnedValue method_set_globalCompositeOperation(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_lineDashOffset(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_shadowColor(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::shadowColor Holds the current shadow color.
static QV4::ReturnedValue method_set_lineWidth(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_shadowColor(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_lineJoin(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_strokeStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty variant QtQuick::Context2D::strokeStyle Holds the current color or style to use for the ...
static QV4::ReturnedValue method_set_shadowBlur(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_textBaseline(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::textBaseline
static QV4::ReturnedValue method_get_shadowOffsetX(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::shadowOffsetX Holds the current shadow offset in the positive h...
static void markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack)
QQuickContext2D * context()
void setContext(QQuickContext2D *context)