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 <QtGui/private/qguisvg_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
92
96#define CHECK_CONTEXT(r) if (!r || !r->d()->context() || !r->d()->context()->bufferValid())
97 THROW_GENERIC_ERROR("Not a Context2D object");
99#define CHECK_CONTEXT_SETTER(r) if (!r || !r->d()->context() || !r->d()->context()->bufferValid())
100 THROW_GENERIC_ERROR("Not a Context2D object");
101#define qClamp(val, min, max) qMin(qMax(val, min), max)
102#define CHECK_RGBA(c) (c == '-' || c == '.' || (c >=0
&& c <= 9
))
105 QByteArray str = name.toQString().toUtf8();
107 char *p = str.data();
108 int len = str.size();
110 if (!p || len > 255 || len <= 7)
111 return QColor::fromString(p);
113 bool isRgb(
false), isHsl(
false), hasAlpha(
false);
116 while (isspace(*p)) p++;
117 if (strncmp(p,
"rgb", 3) == 0)
119 else if (strncmp(p,
"hsl", 3) == 0)
122 return QColor::fromString(p);
125 hasAlpha = (*p ==
'a') ?
true :
false;
131 int rh, gs, bl, alpha = 255;
134 while (isspace(*p)) p++;
135 rh = strtol(p, &p, 10);
137 rh = qRound(rh/100.0 * 255);
140 if (*p++ !=
',')
return QColor();
143 while (isspace(*p)) p++;
144 gs = strtol(p, &p, 10);
146 gs = qRound(gs/100.0 * 255);
149 if (*p++ !=
',')
return QColor();
152 while (isspace(*p)) p++;
153 bl = strtol(p, &p, 10);
155 bl = qRound(bl/100.0 * 255);
160 if (*p++!=
',')
return QColor();
161 while (isspace(*p)) p++;
163 alpha = qRound(qstrtod(p,
const_cast<
const char **>(&p), &ok) * 255);
166 if (*p !=
')')
return QColor();
168 return QColor::fromRgba(qRgba(
qClamp(rh, 0, 255),
qClamp(gs, 0, 255),
qClamp(bl, 0, 255),
qClamp(alpha, 0, 255)));
170 return QColor::fromHsl(
qClamp(rh, 0, 359),
qClamp(gs, 0, 255),
qClamp(bl, 0, 255),
qClamp(alpha, 0, 255));
178 float size = fontSizeToken.trimmed().toFloat(&ok);
182 qWarning().nospace() <<
"Context2D: A font size of " << fontSizeToken <<
" is invalid.";
187
188
189
190
193 const QStringView trimmedToken = fontSizeToken.trimmed();
194 const QStringView unitStr = trimmedToken.right(2);
195 const QStringView value = trimmedToken.left(trimmedToken.size() - 2);
198 if (unitStr == QLatin1String(
"px")) {
199 size = qParseFontSizeFromToken(value, ok);
201 font.setPixelSize(size);
204 }
else if (unitStr == QLatin1String(
"pt")) {
205 size = qParseFontSizeFromToken(value, ok);
207 font.setPointSize(size);
211 qWarning().nospace() <<
"Context2D: Invalid font size unit in font string.";
217
218
219
220
223 QStringList extractedFamilies;
225 QString currentFamily;
226 for (
int index = 0; index < fontFamiliesString.size(); ++index) {
227 const QChar ch = fontFamiliesString.at(index);
228 if (ch == u'"' || ch == u'\'') {
229 if (quoteIndex == -1) {
232 if (ch == fontFamiliesString.at(quoteIndex)) {
234 const QString family = fontFamiliesString.mid(quoteIndex + 1, index - quoteIndex - 1).toString();
235 extractedFamilies.push_back(family);
236 currentFamily.clear();
239 qWarning().nospace() <<
"Context2D: Mismatched quote in font string.";
240 return QStringList();
243 }
else if (ch == u' ' && quoteIndex == -1) {
245 if (!currentFamily.isEmpty()) {
247 extractedFamilies.push_back(currentFamily);
248 currentFamily.clear();
251 currentFamily.push_back(ch);
254 if (!currentFamily.isEmpty()) {
255 if (quoteIndex == -1) {
257 extractedFamilies.push_back(currentFamily);
259 qWarning().nospace() <<
"Context2D: Unclosed quote in font string.";
260 return QStringList();
263 if (extractedFamilies.isEmpty()) {
264 qWarning().nospace() <<
"Context2D: Missing or misplaced font family in font string"
265 <<
" (it must come after the font size).";
267 return extractedFamilies;
271
272
273
274
275
276
277
278
281 for (
const QString &fontFamilyToken : fontFamilyTokens) {
282 if (QFontDatabase::hasFamily(fontFamilyToken)) {
283 font.setFamily(fontFamilyToken);
289 if (fontFamilyToken.compare(QLatin1String(
"serif")) == 0) {
290 styleHint = QFont::Serif;
291 }
else if (fontFamilyToken.compare(QLatin1String(
"sans-serif")) == 0) {
292 styleHint = QFont::SansSerif;
293 }
else if (fontFamilyToken.compare(QLatin1String(
"cursive")) == 0) {
294 styleHint = QFont::Cursive;
295 }
else if (fontFamilyToken.compare(QLatin1String(
"monospace")) == 0) {
296 styleHint = QFont::Monospace;
297 }
else if (fontFamilyToken.compare(QLatin1String(
"fantasy")) == 0) {
298 styleHint = QFont::Fantasy;
300 if (styleHint != -1) {
302 tmp.setStyleHint(
static_cast<QFont::StyleHint>(styleHint));
303 font.setFamily(tmp.defaultFamily());
308 qWarning(
"Context2D: The font families specified are invalid: %s", qPrintable(fontFamilyTokens.join(QString()).trimmed()));
320#define Q_TRY_SET_TOKEN(token, value, setStatement) if
321 (!(usedTokens & token)) {
324}else {
325 qWarning().nospace() << "Context2D: Duplicate token " << QLatin1String(value) << " found in font string.";
326 return currentFont; \
327}
330
331
332
333
335 if (fontString.isEmpty()) {
336 qWarning().nospace() <<
"Context2D: Font string is empty.";
342 int fontSizeEnd = fontString.indexOf(QLatin1String(
"px"));
343 if (fontSizeEnd == -1)
344 fontSizeEnd = fontString.indexOf(QLatin1String(
"pt"));
345 if (fontSizeEnd == -1) {
346 qWarning().nospace() <<
"Context2D: Invalid font size unit in font string.";
350 int fontSizeStart = fontString.lastIndexOf(u' ', fontSizeEnd);
351 if (fontSizeStart == -1) {
364 if (!qSetFontSizeFromToken(newFont, QStringView{fontString}.mid(fontSizeStart, fontSizeEnd - fontSizeStart)))
368 QString remainingFontString = fontString;
369 remainingFontString.remove(fontSizeStart, fontSizeEnd - fontSizeStart);
370 QStringView remainingFontStringRef(remainingFontString);
373 const QStringView fontFamiliesString = remainingFontStringRef.mid(fontSizeStart);
374 remainingFontStringRef.truncate(fontSizeStart);
375 QStringList fontFamilies = qExtractFontFamiliesFromString(fontFamiliesString);
376 if (fontFamilies.isEmpty()) {
379 if (!qSetFontFamilyFromTokens(newFont, fontFamilies))
383 const QStringView trimmedTokensStr = remainingFontStringRef.trimmed();
384 if (trimmedTokensStr.isEmpty()) {
388 const auto tokens = trimmedTokensStr.split(QLatin1Char(
' '));
392 for (
const QStringView &token : tokens) {
393 if (token.compare(QLatin1String(
"normal")) == 0) {
394 if (!(usedTokens & FontStyle) || !(usedTokens & FontVariant) || !(usedTokens & FontWeight)) {
396 if (!(usedTokens & FontStyle)) {
398 usedTokens = usedTokens | FontStyle;
399 }
else if (!(usedTokens & FontVariant)) {
401 usedTokens |= FontVariant;
402 }
else if (!(usedTokens & FontWeight)) {
404 usedTokens |= FontWeight;
407 qWarning().nospace() <<
"Context2D: Duplicate token \"normal\" found in font string.";
410 }
else if (token.compare(QLatin1String(
"bold")) == 0) {
412 }
else if (token.compare(QLatin1String(
"italic")) == 0) {
413 Q_TRY_SET_TOKEN(FontStyle,
"italic", newFont.setStyle(QFont::StyleItalic))
414 }
else if (token.compare(QLatin1String(
"oblique")) == 0) {
415 Q_TRY_SET_TOKEN(FontStyle,
"oblique", newFont.setStyle(QFont::StyleOblique))
416 }
else if (token.compare(QLatin1String(
"small-caps")) == 0) {
417 Q_TRY_SET_TOKEN(FontVariant,
"small-caps", newFont.setCapitalization(QFont::SmallCaps))
419 bool conversionOk =
false;
420 int weight = token.toInt(&conversionOk);
423 newFont.setWeight(QFont::Weight(weight)))
426 qWarning().nospace() <<
"Context2D: Invalid or misplaced token " << token
427 <<
" found in font string.";
468 *m_context = context;
470 m_context =
new QPointer<QQuickContext2D>(context);
474 QPointer<QQuickContext2D>* m_context;
478 void init() { Object::init(); }
502 auto *mm = internalClass->engine->memoryManager;
503 mm->changeUnmanagedHeapSizeUsage(-image->sizeInBytes());
515 static void markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack) {
517 Object::markObjects(that, markStack);
563#if QT_CONFIG(quick_path)
704 int delta = radius ? radius : qFloor(qSqrt(weights.size()) / qreal(2));
705 int filterDim = 2 * delta + 1;
707 QImage dst = QImage(src.size(), src.format());
710 int h = src.height();
712 const QRgb *sr = (
const QRgb *)(src.constBits());
713 int srcStride = src.bytesPerLine() / 4;
715 QRgb *dr = (QRgb*)dst.bits();
716 int dstStride = dst.bytesPerLine() / 4;
718 for (
int y = 0; y < h; ++y) {
719 for (
int x = 0; x < w; ++x) {
733 for (
int cy = 0; cy < filterDim; ++cy) {
734 int scy = sy + cy - delta;
736 if (scy < 0 || scy >= h)
739 const QRgb *sry = sr + scy * srcStride;
741 for (
int cx = 0; cx < filterDim; ++cx) {
742 int scx = sx + cx - delta;
744 if (scx < 0 || scx >= w)
747 const QRgb col = sry[scx];
751 green += qGreen(col);
753 alpha += qAlpha(col);
755 qreal wt = weights[cy * filterDim + cx];
757 redF += qRed(col) * wt;
758 greenF += qGreen(col) * wt;
759 blueF += qBlue(col) * wt;
760 alphaF += qAlpha(col) * wt;
766 dr[x] = qRgba(qRound(red * weights[0]), qRound(green * weights[0]), qRound(blue * weights[0]), qRound(alpha * weights[0]));
768 dr[x] = qRgba(qRound(redF), qRound(greenF), qRound(blueF), qRound(alphaF));
779 int passes = quality? 3: 1;
780 int filterSize = 2 * radius + 1;
781 for (
int i = 0; i < passes; ++i)
782 image = qt_image_convolute_filter(image, QList<qreal>() << 1.0 / (filterSize * filterSize), radius);
787 if (compositeOperator == QLatin1String(
"source-over")) {
788 return QPainter::CompositionMode_SourceOver;
789 }
else if (compositeOperator == QLatin1String(
"source-out")) {
790 return QPainter::CompositionMode_SourceOut;
791 }
else if (compositeOperator == QLatin1String(
"source-in")) {
792 return QPainter::CompositionMode_SourceIn;
793 }
else if (compositeOperator == QLatin1String(
"source-atop")) {
794 return QPainter::CompositionMode_SourceAtop;
795 }
else if (compositeOperator == QLatin1String(
"destination-atop")) {
796 return QPainter::CompositionMode_DestinationAtop;
797 }
else if (compositeOperator == QLatin1String(
"destination-in")) {
798 return QPainter::CompositionMode_DestinationIn;
799 }
else if (compositeOperator == QLatin1String(
"destination-out")) {
800 return QPainter::CompositionMode_DestinationOut;
801 }
else if (compositeOperator == QLatin1String(
"destination-over")) {
802 return QPainter::CompositionMode_DestinationOver;
803 }
else if (compositeOperator == QLatin1String(
"lighter")) {
804 return QPainter::CompositionMode_Plus;
805 }
else if (compositeOperator == QLatin1String(
"copy")) {
806 return QPainter::CompositionMode_Source;
807 }
else if (compositeOperator == QLatin1String(
"xor")) {
808 return QPainter::CompositionMode_Xor;
809 }
else if (compositeOperator == QLatin1String(
"qt-clear")) {
810 return QPainter::CompositionMode_Clear;
811 }
else if (compositeOperator == QLatin1String(
"qt-destination")) {
812 return QPainter::CompositionMode_Destination;
813 }
else if (compositeOperator == QLatin1String(
"qt-multiply")) {
814 return QPainter::CompositionMode_Multiply;
815 }
else if (compositeOperator == QLatin1String(
"qt-screen")) {
816 return QPainter::CompositionMode_Screen;
817 }
else if (compositeOperator == QLatin1String(
"qt-overlay")) {
818 return QPainter::CompositionMode_Overlay;
819 }
else if (compositeOperator == QLatin1String(
"qt-darken")) {
820 return QPainter::CompositionMode_Darken;
821 }
else if (compositeOperator == QLatin1String(
"qt-lighten")) {
822 return QPainter::CompositionMode_Lighten;
823 }
else if (compositeOperator == QLatin1String(
"qt-color-dodge")) {
824 return QPainter::CompositionMode_ColorDodge;
825 }
else if (compositeOperator == QLatin1String(
"qt-color-burn")) {
826 return QPainter::CompositionMode_ColorBurn;
827 }
else if (compositeOperator == QLatin1String(
"qt-hard-light")) {
828 return QPainter::CompositionMode_HardLight;
829 }
else if (compositeOperator == QLatin1String(
"qt-soft-light")) {
830 return QPainter::CompositionMode_SoftLight;
831 }
else if (compositeOperator == QLatin1String(
"qt-difference")) {
832 return QPainter::CompositionMode_Difference;
833 }
else if (compositeOperator == QLatin1String(
"qt-exclusion")) {
834 return QPainter::CompositionMode_Exclusion;
836 return QPainter::CompositionMode_SourceOver;
842 case QPainter::CompositionMode_SourceOver:
843 return QStringLiteral(
"source-over");
844 case QPainter::CompositionMode_DestinationOver:
845 return QStringLiteral(
"destination-over");
846 case QPainter::CompositionMode_Clear:
847 return QStringLiteral(
"qt-clear");
848 case QPainter::CompositionMode_Source:
849 return QStringLiteral(
"copy");
850 case QPainter::CompositionMode_Destination:
851 return QStringLiteral(
"qt-destination");
852 case QPainter::CompositionMode_SourceIn:
853 return QStringLiteral(
"source-in");
854 case QPainter::CompositionMode_DestinationIn:
855 return QStringLiteral(
"destination-in");
856 case QPainter::CompositionMode_SourceOut:
857 return QStringLiteral(
"source-out");
858 case QPainter::CompositionMode_DestinationOut:
859 return QStringLiteral(
"destination-out");
860 case QPainter::CompositionMode_SourceAtop:
861 return QStringLiteral(
"source-atop");
862 case QPainter::CompositionMode_DestinationAtop:
863 return QStringLiteral(
"destination-atop");
864 case QPainter::CompositionMode_Xor:
865 return QStringLiteral(
"xor");
866 case QPainter::CompositionMode_Plus:
867 return QStringLiteral(
"lighter");
868 case QPainter::CompositionMode_Multiply:
869 return QStringLiteral(
"qt-multiply");
870 case QPainter::CompositionMode_Screen:
871 return QStringLiteral(
"qt-screen");
872 case QPainter::CompositionMode_Overlay:
873 return QStringLiteral(
"qt-overlay");
874 case QPainter::CompositionMode_Darken:
875 return QStringLiteral(
"qt-darken");
876 case QPainter::CompositionMode_Lighten:
877 return QStringLiteral(
"lighter");
878 case QPainter::CompositionMode_ColorDodge:
879 return QStringLiteral(
"qt-color-dodge");
880 case QPainter::CompositionMode_ColorBurn:
881 return QStringLiteral(
"qt-color-burn");
882 case QPainter::CompositionMode_HardLight:
883 return QStringLiteral(
"qt-hard-light");
884 case QPainter::CompositionMode_SoftLight:
885 return QStringLiteral(
"qt-soft-light");
886 case QPainter::CompositionMode_Difference:
887 return QStringLiteral(
"qt-difference");
888 case QPainter::CompositionMode_Exclusion:
889 return QStringLiteral(
"qt-exclusion");
902 static bool virtualPut(QV4::Managed *m, QV4::PropertyKey id,
const QV4::Value &value, Value *receiver);
911 QV4::Scope scope(internalClass->engine);
912 QV4::ScopedObject o(scope,
this);
913 o->setArrayType(QV4::Heap::ArrayData::Custom);
931 pixelData = QV4::Value::undefinedValue();
933 QV4::Scope scope(internalClass->engine);
934 QV4::ScopedObject o(scope,
this);
936 o->defineAccessorProperty(QStringLiteral(
"width"), ::QQuickJSContext2DImageData::method_get_width,
nullptr);
937 o->defineAccessorProperty(QStringLiteral(
"height"), ::QQuickJSContext2DImageData::method_get_height,
nullptr);
938 o->defineAccessorProperty(QStringLiteral(
"data"), ::QQuickJSContext2DImageData::method_get_data,
nullptr);
945 QV4::Scope scope(v4);
947 QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, scope.engine->memoryManager->allocate<QQuickJSContext2DPixelData>());
948 v4->memoryManager->changeUnmanagedHeapSizeUsage(image.sizeInBytes());
949 QV4::ScopedObject p(scope, ed->pixelArrayProto.value());
950 pixelData->setPrototypeOf(p);
952 if (image.isNull()) {
953 *pixelData->d()->image = QImage(qRound(w), qRound(h), QImage::Format_ARGB32);
954 pixelData->d()->image->fill(0x00000000);
957 Q_ASSERT(qAbs(image.width() - qRound(w * image.devicePixelRatio())) <= 1 && qAbs(image.height() - qRound(h * image.devicePixelRatio())) <= 1);
958 *pixelData->d()->image = image.format() == QImage::Format_ARGB32 ? std::move(image) : std::move(image).convertToFormat(QImage::Format_ARGB32);
961 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, scope.engine->memoryManager->allocate<QQuickJSContext2DImageData>());
962 imageData->d()->pixelData = pixelData.asReturnedValue();
963 return imageData.asReturnedValue();
969
970
971
972
973
974QV4::ReturnedValue
QQuickJSContext2DPrototype::method_get_canvas(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
977 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
980 RETURN_RESULT(QV4::QObjectWrapper::wrap(scope.engine, r->d()->context()->canvas()));
984
985
986
987
988
989QV4::ReturnedValue
QQuickJSContext2DPrototype::method_restore(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
992 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
995 r->d()->context()->popState();
996 RETURN_RESULT(thisObject->asReturnedValue());
1000
1001
1002
1005 QV4::Scope scope(b);
1006 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1009 r->d()->context()->reset();
1011 RETURN_RESULT(thisObject->asReturnedValue());
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
1043
1046 QV4::Scope scope(b);
1047 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1050 r->d()->context()->pushState();
1052 RETURN_RESULT(*thisObject);
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075QV4::ReturnedValue
QQuickJSContext2DPrototype::method_rotate(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1077 QV4::Scope scope(b);
1078 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1082 r->d()->context()->rotate(argv[0].toNumber());
1083 RETURN_RESULT(*thisObject);
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104QV4::ReturnedValue
QQuickJSContext2DPrototype::method_scale(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1106 QV4::Scope scope(b);
1107 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1112 r->d()->context()->scale(argv[0].toNumber(), argv[1].toNumber());
1113 RETURN_RESULT(*thisObject);
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
1149
1150
1151
1152
1153
1154QV4::ReturnedValue
QQuickJSContext2DPrototype::method_setTransform(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1156 QV4::Scope scope(b);
1157 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1162 r->d()->context()->setTransform( argv[0].toNumber()
1163 , argv[1].toNumber()
1164 , argv[2].toNumber()
1165 , argv[3].toNumber()
1166 , argv[4].toNumber()
1167 , argv[5].toNumber());
1169 RETURN_RESULT(*thisObject);
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187QV4::ReturnedValue
QQuickJSContext2DPrototype::method_transform(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1189 QV4::Scope scope(b);
1190 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1194 r->d()->context()->transform( argv[0].toNumber()
1195 , argv[1].toNumber()
1196 , argv[2].toNumber()
1197 , argv[3].toNumber()
1198 , argv[4].toNumber()
1199 , argv[5].toNumber());
1201 RETURN_RESULT(*thisObject);
1206
1207
1208
1209
1210
1211
1212
1213
1214QV4::ReturnedValue
QQuickJSContext2DPrototype::method_translate(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1216 QV4::Scope scope(b);
1217 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1221 r->d()->context()->translate(argv[0].toNumber(), argv[1].toNumber());
1222 RETURN_RESULT(*thisObject);
1228
1229
1230
1231
1232
1233
1234
1235QV4::ReturnedValue
QQuickJSContext2DPrototype::method_resetTransform(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1237 QV4::Scope scope(b);
1238 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1241 r->d()->context()->setTransform(1, 0, 0, 1, 0, 0);
1243 RETURN_RESULT(*thisObject);
1249
1250
1251
1252
1253
1254QV4::ReturnedValue
QQuickJSContext2DPrototype::method_shear(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1256 QV4::Scope scope(b);
1257 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1261 r->d()->context()->shear(argv[0].toNumber(), argv[1].toNumber());
1263 RETURN_RESULT(*thisObject);
1269
1270
1271
1272
1273
1274
1275QV4::ReturnedValue
QQuickJSContext2D::method_get_globalAlpha(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1277 QV4::Scope scope(b);
1278 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1281 RETURN_RESULT(QV4::Encode(r->d()->context()->state.globalAlpha));
1284QV4::ReturnedValue
QQuickJSContext2D::method_set_globalAlpha(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1286 QV4::Scope scope(b);
1287 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1290 double globalAlpha = argc ? argv[0].toNumber() : qt_qnan();
1293 if (!qt_is_finite(globalAlpha))
1296 if (globalAlpha >= 0.0 && globalAlpha <= 1.0 && r->d()->context()->state.globalAlpha != globalAlpha) {
1297 r->d()->context()->state.globalAlpha = globalAlpha;
1298 r->d()->context()->buffer()->setGlobalAlpha(r->d()->context()->state.globalAlpha);
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
1376
1377
1378
1379
1380
1381QV4::ReturnedValue
QQuickJSContext2D::method_get_globalCompositeOperation(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1383 QV4::Scope scope(b);
1384 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1387 RETURN_RESULT(scope.engine->newString(qt_composite_mode_to_string(r->d()->context()->state.globalCompositeOperation)));
1390QV4::ReturnedValue
QQuickJSContext2D::method_set_globalCompositeOperation(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1392 QV4::Scope scope(b);
1393 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1399 QString mode = argv[0].toQString();
1400 QPainter::CompositionMode cm = qt_composite_mode_from_string(mode);
1401 if (cm == QPainter::CompositionMode_SourceOver && mode != QLatin1String(
"source-over"))
1404 if (cm != r->d()->context()->state.globalCompositeOperation) {
1405 r->d()->context()->state.globalCompositeOperation = cm;
1406 r->d()->context()->buffer()->setGlobalCompositeOperation(cm);
1414 if (color.isValid()) {
1415 if (color.alpha() == 255)
1416 return color.name();
1417 QString alphaString = QString::number(color.alphaF(),
'f');
1418 while (alphaString.endsWith(QLatin1Char(
'0')))
1419 alphaString.chop(1);
1420 if (alphaString.endsWith(QLatin1Char(
'.')))
1421 alphaString += QLatin1Char(
'0');
1422 return QString::fromLatin1(
"rgba(%1, %2, %3, %4)").arg(color.red()).arg(color.green()).arg(color.blue()).arg(alphaString);
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450QV4::ReturnedValue
QQuickJSContext2D::method_get_fillStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1452 QV4::Scope scope(b);
1453 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1456 if (
auto str = makeColorString(r->d()->context()->state.fillStyle.color().toRgb()); !str.isEmpty())
1457 RETURN_RESULT(scope.engine->newString(std::move(str)));
1458 RETURN_RESULT(r->d()->context()->m_fillStyle.value());
1461QV4::ReturnedValue
QQuickJSContext2D::method_set_fillStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1463 QV4::Scope scope(b);
1464 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1467 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
1469 if (value->as<Object>()) {
1470 QColor color = QV4::ExecutionEngine::toVariant(value, QMetaType::fromType<QColor>()).value<QColor>();
1471 if (color.isValid()) {
1472 r->d()->context()->state.fillStyle = color;
1473 r->d()->context()->buffer()->setFillStyle(color);
1474 r->d()->context()->m_fillStyle.set(scope.engine, value);
1476 QV4::Scoped<QQuickContext2DStyle> style(scope, value->as<QQuickContext2DStyle>());
1477 if (style && *style->d()->brush != r->d()->context()->state.fillStyle) {
1478 r->d()->context()->state.fillStyle = *style->d()->brush;
1479 r->d()->context()->buffer()->setFillStyle(*style->d()->brush, style->d()->patternRepeatX, style->d()->patternRepeatY);
1480 r->d()->context()->m_fillStyle.set(scope.engine, value);
1481 r->d()->context()->state.fillPatternRepeatX = style->d()->patternRepeatX;
1482 r->d()->context()->state.fillPatternRepeatY = style->d()->patternRepeatY;
1485 }
else if (value->isString()) {
1486 QColor color = qt_color_from_string(value);
1487 if (color.isValid() && r->d()->context()->state.fillStyle != QBrush(color)) {
1488 r->d()->context()->state.fillStyle = QBrush(color);
1489 r->d()->context()->buffer()->setFillStyle(r->d()->context()->state.fillStyle);
1490 r->d()->context()->m_fillStyle.set(scope.engine, value);
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508QV4::ReturnedValue
QQuickJSContext2D::method_get_fillRule(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1510 QV4::Scope scope(b);
1511 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1514 RETURN_RESULT(scope.engine->fromVariant(r->d()->context()->state.fillRule));
1517QV4::ReturnedValue
QQuickJSContext2D::method_set_fillRule(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1519 QV4::Scope scope(b);
1520 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1523 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
1525 if ((value->isString() && value->toQString() == QLatin1String(
"WindingFill"))
1526 || (value->isInt32() && value->integerValue() == Qt::WindingFill)) {
1527 r->d()->context()->state.fillRule = Qt::WindingFill;
1528 }
else if ((value->isString() && value->toQStringNoThrow() == QLatin1String(
"OddEvenFill"))
1529 || (value->isInt32() && value->integerValue() == Qt::OddEvenFill)) {
1530 r->d()->context()->state.fillRule = Qt::OddEvenFill;
1534 r->d()->context()->m_path.setFillRule(r->d()->context()->state.fillRule);
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550QV4::ReturnedValue
QQuickJSContext2D::method_get_strokeStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1552 QV4::Scope scope(b);
1553 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1556 if (
auto str = makeColorString(r->d()->context()->state.strokeStyle.color().toRgb()); !str.isEmpty())
1557 RETURN_RESULT(scope.engine->newString(std::move(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")
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 QList<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
2084
2085QV4::ReturnedValue
QQuickJSContext2DPrototype::method_setLineDash(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2087 QV4::Scope scope(b);
2088 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2094 QV4::ScopedArrayObject array(scope, argv[0]);
2098 QV4::ScopedValue v(scope);
2099 const uint arrayLength = array->getLength();
2100 QList<qreal> dashes;
2101 dashes.reserve(arrayLength);
2102 for (uint i = 0; i < arrayLength; ++i) {
2104 const double number = v->toNumber();
2106 if (!qt_is_finite(number) || (number < 0))
2109 dashes.append(v->toNumber());
2111 if (dashes.size() % 2 != 0) {
2115 r->d()->context()->state.lineDash = dashes;
2116 r->d()->context()->buffer()->setLineDash(dashes);
2122
2123
2124
2125
2126
2127
2128
2129
2130QV4::ReturnedValue
QQuickJSContext2D::method_get_lineDashOffset(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2132 QV4::Scope scope(b);
2133 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2136 RETURN_RESULT(QV4::Encode(r->d()->context()->state.lineDashOffset));
2139QV4::ReturnedValue
QQuickJSContext2D::method_set_lineDashOffset(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2141 QV4::Scope scope(b);
2142 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2145 const qreal offset = argc ? argv[0].toNumber() : -1;
2147 if (qt_is_finite(offset) && offset != r->d()->context()->state.lineDashOffset) {
2148 r->d()->context()->state.lineDashOffset = offset;
2149 r->d()->context()->buffer()->setLineDashOffset(offset);
2157
2158
2159
2160QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowBlur(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2162 QV4::Scope scope(b);
2163 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2166 RETURN_RESULT(QV4::Encode(r->d()->context()->state.shadowBlur));
2169QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowBlur(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2171 QV4::Scope scope(b);
2172 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2175 qreal blur = argc ? argv[0].toNumber() : -1;
2177 if (blur > 0 && qt_is_finite(blur) && blur != r->d()->context()->state.shadowBlur) {
2178 r->d()->context()->state.shadowBlur = blur;
2179 r->d()->context()->buffer()->setShadowBlur(blur);
2185
2186
2187
2188QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowColor(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2190 QV4::Scope scope(b);
2191 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2194 RETURN_RESULT(scope.engine->newString(r->d()->context()->state.shadowColor.name()));
2197QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowColor(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2199 QV4::Scope scope(b);
2200 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2205 color = qt_color_from_string(argv[0]);
2207 if (color.isValid() && color != r->d()->context()->state.shadowColor) {
2208 r->d()->context()->state.shadowColor = color;
2209 r->d()->context()->buffer()->setShadowColor(color);
2216
2217
2218
2219
2220
2221QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowOffsetX(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2223 QV4::Scope scope(b);
2224 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2227 RETURN_RESULT(QV4::Encode(r->d()->context()->state.shadowOffsetX));
2230QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowOffsetX(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2232 QV4::Scope scope(b);
2233 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2236 qreal offsetX = argc ? argv[0].toNumber() : qt_qnan();
2237 if (qt_is_finite(offsetX) && offsetX != r->d()->context()->state.shadowOffsetX) {
2238 r->d()->context()->state.shadowOffsetX = offsetX;
2239 r->d()->context()->buffer()->setShadowOffsetX(offsetX);
2244
2245
2246
2247
2248
2249QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowOffsetY(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2251 QV4::Scope scope(b);
2252 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2255 RETURN_RESULT(QV4::Encode(r->d()->context()->state.shadowOffsetY));
2258QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowOffsetY(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2260 QV4::Scope scope(b);
2261 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2264 qreal offsetY = argc ? argv[0].toNumber() : qt_qnan();
2265 if (qt_is_finite(offsetY) && offsetY != r->d()->context()->state.shadowOffsetY) {
2266 r->d()->context()->state.shadowOffsetY = offsetY;
2267 r->d()->context()->buffer()->setShadowOffsetY(offsetY);
2272#if QT_CONFIG(quick_path)
2273QV4::ReturnedValue QQuickJSContext2D::method_get_path(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2275 QV4::Scope scope(b);
2276 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2279 RETURN_RESULT(r->d()->context()->m_v4path.value());
2282QV4::ReturnedValue QQuickJSContext2D::method_set_path(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2284 QV4::Scope scope(b);
2285 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2286 CHECK_CONTEXT_SETTER(r)
2288 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
2289 r->d()->context()->beginPath();
2290 QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, value);
2291 if (!!qobjectWrapper) {
2292 if (QQuickPath *path = qobject_cast<QQuickPath*>(qobjectWrapper->object()))
2293 r->d()->context()->m_path = path->path();
2295 QString path =value->toQStringNoThrow();
2296 std::optional<QPainterPath> qpath = QGuiSvg::parsePath(path);
2298 r->d()->context()->m_path = qpath.value();
2300 r->d()->context()->m_v4path.set(scope.engine, value);
2307
2308
2309
2310
2311
2312QV4::ReturnedValue
QQuickJSContext2DPrototype::method_clearRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2314 QV4::Scope scope(b);
2315 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2320 r->d()->context()->clearRect(argv[0].toNumber(),
2323 argv[3].toNumber());
2325 RETURN_RESULT(*thisObject);
2329
2330
2331
2332
2333
2334
2335QV4::ReturnedValue
QQuickJSContext2DPrototype::method_fillRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2337 QV4::Scope scope(b);
2338 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2342 r->d()->context()->fillRect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2343 RETURN_RESULT(*thisObject);
2348
2349
2350
2351
2352
2353
2354
2355QV4::ReturnedValue
QQuickJSContext2DPrototype::method_strokeRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2357 QV4::Scope scope(b);
2358 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2362 r->d()->context()->strokeRect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2364 RETURN_RESULT(*thisObject);
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391QV4::ReturnedValue
QQuickJSContext2DPrototype::method_arc(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2393 QV4::Scope scope(b);
2394 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2398 bool antiClockwise =
false;
2401 antiClockwise = argv[5].toBoolean();
2403 qreal radius = argv[2].toNumber();
2405 if (qt_is_finite(radius) && radius < 0)
2406 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"Incorrect argument radius");
2408 r->d()->context()->arc(argv[0].toNumber(),
2416 RETURN_RESULT(*thisObject);
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444QV4::ReturnedValue
QQuickJSContext2DPrototype::method_arcTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2446 QV4::Scope scope(b);
2447 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2451 qreal radius = argv[4].toNumber();
2453 if (qt_is_finite(radius) && radius < 0)
2454 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"Incorrect argument radius");
2456 r->d()->context()->arcTo(argv[0].toNumber(),
2463 RETURN_RESULT(*thisObject);
2468
2469
2470
2471
2472QV4::ReturnedValue
QQuickJSContext2DPrototype::method_beginPath(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2474 QV4::Scope scope(b);
2475 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2478 r->d()->context()->beginPath();
2480 RETURN_RESULT(*thisObject);
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507QV4::ReturnedValue
QQuickJSContext2DPrototype::method_bezierCurveTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2509 QV4::Scope scope(b);
2510 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2514 qreal cp1x = argv[0].toNumber();
2515 qreal cp1y = argv[1].toNumber();
2516 qreal cp2x = argv[2].toNumber();
2517 qreal cp2y = argv[3].toNumber();
2518 qreal x = argv[4].toNumber();
2519 qreal y = argv[5].toNumber();
2521 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))
2524 r->d()->context()->bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
2526 RETURN_RESULT(*thisObject);
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2556 QV4::Scope scope(b);
2557 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2560 r->d()->context()->clip();
2561 RETURN_RESULT(*thisObject);
2565
2566
2567
2568
2569
2570
2571QV4::ReturnedValue
QQuickJSContext2DPrototype::method_closePath(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2573 QV4::Scope scope(b);
2574 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2577 r->d()->context()->closePath();
2579 RETURN_RESULT(*thisObject);
2583
2584
2585
2586
2587
2588
2589
2590
2593 QV4::Scope scope(b);
2594 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2596 r->d()->context()->fill();
2597 RETURN_RESULT(*thisObject);
2601
2602
2603
2604
2605QV4::ReturnedValue
QQuickJSContext2DPrototype::method_lineTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2607 QV4::Scope scope(b);
2608 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2612 qreal x = argv[0].toNumber();
2613 qreal y = argv[1].toNumber();
2615 if (!qt_is_finite(x) || !qt_is_finite(y))
2618 r->d()->context()->lineTo(x, y);
2621 RETURN_RESULT(*thisObject);
2625
2626
2627
2628
2629QV4::ReturnedValue
QQuickJSContext2DPrototype::method_moveTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2631 QV4::Scope scope(b);
2632 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2636 qreal x = argv[0].toNumber();
2637 qreal y = argv[1].toNumber();
2639 if (!qt_is_finite(x) || !qt_is_finite(y))
2641 r->d()->context()->moveTo(x, y);
2644 RETURN_RESULT(*thisObject);
2648
2649
2650
2651
2652
2653
2654
2655QV4::ReturnedValue
QQuickJSContext2DPrototype::method_quadraticCurveTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2657 QV4::Scope scope(b);
2658 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2662 qreal cpx = argv[0].toNumber();
2663 qreal cpy = argv[1].toNumber();
2664 qreal x = argv[2].toNumber();
2665 qreal y = argv[3].toNumber();
2667 if (!qt_is_finite(cpx) || !qt_is_finite(cpy) || !qt_is_finite(x) || !qt_is_finite(y))
2670 r->d()->context()->quadraticCurveTo(cpx, cpy, x, y);
2673 RETURN_RESULT(*thisObject);
2677
2678
2679
2680
2681
2682QV4::ReturnedValue
QQuickJSContext2DPrototype::method_rect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2684 QV4::Scope scope(b);
2685 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2689 r->d()->context()->rect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2690 RETURN_RESULT(*thisObject);
2695
2696
2697
2698
2699
2700
2701QV4::ReturnedValue
QQuickJSContext2DPrototype::method_roundedRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2703 QV4::Scope scope(b);
2704 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2708 r->d()->context()->roundedRect(argv[0].toNumber()
2709 , argv[1].toNumber()
2710 , argv[2].toNumber()
2711 , argv[3].toNumber()
2712 , argv[4].toNumber()
2713 , argv[5].toNumber());
2714 RETURN_RESULT(*thisObject);
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728QV4::ReturnedValue
QQuickJSContext2DPrototype::method_ellipse(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2730 QV4::Scope scope(b);
2731 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2735 r->d()->context()->ellipse(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2737 RETURN_RESULT(*thisObject);
2742
2743
2744
2745
2746
2747
2748
2749
2750QV4::ReturnedValue
QQuickJSContext2DPrototype::method_text(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2752 QV4::Scope scope(b);
2753 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2757 qreal x = argv[1].toNumber();
2758 qreal y = argv[2].toNumber();
2760 if (!qt_is_finite(x) || !qt_is_finite(y))
2762 r->d()->context()->text(argv[0].toQStringNoThrow(), x, y);
2765 RETURN_RESULT(*thisObject);
2769
2770
2771
2772
2773
2774
2777 QV4::Scope scope(b);
2778 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2781 r->d()->context()->stroke();
2782 RETURN_RESULT(*thisObject);
2787
2788
2789
2790
2791
2792
2793QV4::ReturnedValue
QQuickJSContext2DPrototype::method_isPointInPath(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2795 QV4::Scope scope(b);
2796 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2799 bool pointInPath =
false;
2801 pointInPath = r->d()->context()->isPointInPath(argv[0].toNumber(), argv[1].toNumber());
2802 RETURN_RESULT(QV4::Value::fromBoolean(pointInPath).asReturnedValue());
2807 QV4::Scope scope(b);
2808 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"Context2D::drawFocusRing is not supported");
2811QV4::ReturnedValue
QQuickJSContext2DPrototype::method_setCaretSelectionRect(
const QV4::FunctionObject *b,
const QV4::Value *,
const QV4::Value *,
int)
2813 QV4::Scope scope(b);
2814 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"Context2D::setCaretSelectionRect is not supported");
2819 QV4::Scope scope(b);
2820 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"Context2D::caretBlinkRate is not supported");
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846QV4::ReturnedValue
QQuickJSContext2D::method_get_font(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2848 QV4::Scope scope(b);
2849 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2852 RETURN_RESULT(scope.engine->newString(r->d()->context()->state.font.toString()));
2855QV4::ReturnedValue
QQuickJSContext2D::method_set_font(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2857 QV4::Scope scope(b);
2858 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2861 QV4::ScopedString s(scope, argc ? argv[0] : QV4::Value::undefinedValue(), QV4::ScopedString::Convert);
2862 if (scope.hasException())
2864 QFont font = qt_font_from_string(s->toQString(), r->d()->context()->state.font);
2865 if (font != r->d()->context()->state.font) {
2866 r->d()->context()->state.font = font;
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886QV4::ReturnedValue
QQuickJSContext2D::method_get_textAlign(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2888 QV4::Scope scope(b);
2889 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2892 switch (r->d()->context()->state.textAlign) {
2894 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"end")));
2896 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"left")));
2898 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"right")));
2900 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"center")));
2905 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"start")));
2908QV4::ReturnedValue
QQuickJSContext2D::method_set_textAlign(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2910 QV4::Scope scope(b);
2911 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2914 QV4::ScopedString s(scope, argc ? argv[0] : QV4::Value::undefinedValue(), QV4::ScopedString::Convert);
2915 if (scope.hasException())
2917 QString textAlign = s->toQString();
2920 if (textAlign == QLatin1String(
"start"))
2922 else if (textAlign == QLatin1String(
"end"))
2924 else if (textAlign == QLatin1String(
"left"))
2926 else if (textAlign == QLatin1String(
"right"))
2928 else if (textAlign == QLatin1String(
"center"))
2933 if (ta != r->d()->context()->state.textAlign)
2934 r->d()->context()->state.textAlign = ta;
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953QV4::ReturnedValue
QQuickJSContext2D::method_get_textBaseline(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2955 QV4::Scope scope(b);
2956 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2959 switch (r->d()->context()->state.textBaseline) {
2960 case QQuickContext2D::Hanging:
2961 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"hanging")));
2962 case QQuickContext2D::Top:
2963 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"top")));
2964 case QQuickContext2D::Bottom:
2965 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"bottom")));
2966 case QQuickContext2D::Middle:
2967 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"middle")));
2968 case QQuickContext2D::Alphabetic:
2972 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"alphabetic")));
2975QV4::ReturnedValue
QQuickJSContext2D::method_set_textBaseline(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2977 QV4::Scope scope(b);
2978 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2980 QV4::ScopedString s(scope, argc ? argv[0] : QV4::Value::undefinedValue(), QV4::ScopedString::Convert);
2981 if (scope.hasException())
2983 QString textBaseline = s->toQString();
2985 QQuickContext2D::TextBaseLineType tb;
2986 if (textBaseline == QLatin1String(
"alphabetic"))
2987 tb = QQuickContext2D::Alphabetic;
2988 else if (textBaseline == QLatin1String(
"hanging"))
2989 tb = QQuickContext2D::Hanging;
2990 else if (textBaseline == QLatin1String(
"top"))
2991 tb = QQuickContext2D::Top;
2992 else if (textBaseline == QLatin1String(
"bottom"))
2993 tb = QQuickContext2D::Bottom;
2994 else if (textBaseline == QLatin1String(
"middle"))
2995 tb = QQuickContext2D::Middle;
2999 if (tb != r->d()->context()->state.textBaseline)
3000 r->d()->context()->state.textBaseline = tb;
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015QV4::ReturnedValue
QQuickJSContext2DPrototype::method_fillText(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3017 QV4::Scope scope(b);
3018 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3022 qreal x = argv[1].toNumber();
3023 qreal y = argv[2].toNumber();
3024 if (!qt_is_finite(x) || !qt_is_finite(y))
3026 QPainterPath textPath = r->d()->context()->createTextGlyphs(x, y, argv[0].toQStringNoThrow());
3027 r->d()->context()->buffer()->fill(textPath);
3030 RETURN_RESULT(*thisObject);
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042QV4::ReturnedValue
QQuickJSContext2DPrototype::method_strokeText(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3044 QV4::Scope scope(b);
3045 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3049 r->d()->context()->drawText(argv[0].toQStringNoThrow(), argv[1].toNumber(), argv[2].toNumber(),
false);
3051 RETURN_RESULT(*thisObject);
3055
3056
3057
3058
3059
3060
3061QV4::ReturnedValue
QQuickJSContext2DPrototype::method_measureText(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3063 QV4::Scope scope(b);
3064 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3068 QFontMetrics fm(r->d()->context()->state.font);
3069 uint width = fm.horizontalAdvance(argv[0].toQStringNoThrow());
3070 QV4::ScopedObject tm(scope, scope.engine->newObject());
3071 tm->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral(
"width"))).getPointer(),
3072 QV4::ScopedValue(scope, QV4::Value::fromDouble(width)));
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137QV4::ReturnedValue
QQuickJSContext2DPrototype::method_drawImage(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3139 QV4::Scope scope(b);
3140 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3143 qreal sx, sy, sw, sh, dx, dy, dw, dh;
3149 if (!r->d()->context()->state.invertibleCTM)
3152 QQmlRefPointer<QQuickCanvasPixmap> pixmap;
3154 QV4::ScopedValue arg(scope, argv[0]);
3155 if (arg->isString()) {
3156 QUrl url(arg->toQString());
3158 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3160 pixmap = r->d()->context()->createPixmap(url);
3161 }
else if (arg->isObject()) {
3162 QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, arg);
3163 if (!!qobjectWrapper) {
3164 if (QQuickImage *imageItem = qobject_cast<QQuickImage*>(qobjectWrapper->object())) {
3165 pixmap = r->d()->context()->createPixmap(imageItem->source());
3167 QImage img = canvas->toImage();
3169 pixmap.adopt(
new QQuickCanvasPixmap(img));
3171 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3174 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, arg);
3176 QV4::Scoped<QQuickJSContext2DPixelData> pix(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3177 if (pix && !pix->d()->image->isNull()) {
3178 pixmap.adopt(
new QQuickCanvasPixmap(*pix->d()->image));
3180 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3183 QUrl url(arg->toQStringNoThrow());
3185 pixmap = r->d()->context()->createPixmap(url);
3187 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3191 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3194 if (pixmap.isNull() || !pixmap->isValid())
3198 sx = argv[1].toNumber();
3199 sy = argv[2].toNumber();
3200 sw = argv[3].toNumber();
3201 sh = argv[4].toNumber();
3202 dx = argv[5].toNumber();
3203 dy = argv[6].toNumber();
3204 dw = argv[7].toNumber();
3205 dh = argv[8].toNumber();
3206 }
else if (argc >= 5) {
3209 sw = pixmap->width();
3210 sh = pixmap->height();
3211 dx = argv[1].toNumber();
3212 dy = argv[2].toNumber();
3213 dw = argv[3].toNumber();
3214 dh = argv[4].toNumber();
3215 }
else if (argc >= 3) {
3216 dx = argv[1].toNumber();
3217 dy = argv[2].toNumber();
3220 sw = pixmap->width();
3221 sh = pixmap->height();
3228 if (!qt_is_finite(sx)
3229 || !qt_is_finite(sy)
3230 || !qt_is_finite(sw)
3231 || !qt_is_finite(sh)
3232 || !qt_is_finite(dx)
3233 || !qt_is_finite(dy)
3234 || !qt_is_finite(dw)
3235 || !qt_is_finite(dh))
3242 || sx + sw > pixmap->width()
3243 || sy + sh > pixmap->height()
3244 || sx + sw < 0 || sy + sh < 0) {
3245 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"drawImage(), index size error");
3248 r->d()->context()->buffer()->drawPixmap(pixmap, QRectF(sx, sy, sw, sh), QRectF(dx, dy, dw, dh));
3250 RETURN_RESULT(*thisObject);
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3274
3275
3276
3277QV4::ReturnedValue
QQuickJSContext2DImageData::method_get_width(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3279 QV4::Scope scope(b);
3280 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
3283 QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3284 int width = r ? r->d()->image->width() : 0;
3285 RETURN_RESULT(QV4::Encode(width));
3289
3290
3291
3292QV4::ReturnedValue
QQuickJSContext2DImageData::method_get_height(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3294 QV4::Scope scope(b);
3295 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
3298 QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3299 int height = r ? r->d()->image->height() : 0;
3300 RETURN_RESULT(QV4::Encode(height));
3304
3305
3306
3307QV4::ReturnedValue
QQuickJSContext2DImageData::method_get_data(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3309 QV4::Scope scope(b);
3310 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
3313 RETURN_RESULT(imageData->d()->pixelData);
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3329
3330
3331
3332
3333
3334QV4::ReturnedValue
QQuickJSContext2DPixelData::proto_get_length(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3336 QV4::Scope scope(b);
3337 QV4::Scoped<QQuickJSContext2DPixelData> r(scope, thisObject->as<QQuickJSContext2DPixelData>());
3338 if (!r || r->d()->image->isNull())
3341 RETURN_RESULT(QV4::Encode(r->d()->image->width() * r->d()->image->height() * 4));
3344QV4::ReturnedValue
QQuickJSContext2DPixelData::virtualGet(
const QV4::Managed *m, QV4::PropertyKey id,
const QV4::Value *receiver,
bool *hasProperty)
3346 if (!id.isArrayIndex())
3347 return QV4::Object::virtualGet(m, id, receiver, hasProperty);
3349 uint index = id.asArrayIndex();
3352 QV4::Scope scope(v4);
3353 QV4::Scoped<QQuickJSContext2DPixelData> r(scope,
static_cast<
const QQuickJSContext2DPixelData *>(m));
3355 if (index <
static_cast<quint32>(r->d()->image->width() * r->d()->image->height() * 4)) {
3357 *hasProperty =
true;
3358 const quint32 w = r->d()->image->width();
3359 const quint32 row = (index / 4) / w;
3360 const quint32 col = (index / 4) % w;
3361 const QRgb* pixel =
reinterpret_cast<
const QRgb*>(r->d()->image->constScanLine(row));
3363 switch (index % 4) {
3365 return QV4::Encode(qRed(*pixel));
3367 return QV4::Encode(qGreen(*pixel));
3369 return QV4::Encode(qBlue(*pixel));
3371 return QV4::Encode(qAlpha(*pixel));
3376 *hasProperty =
false;
3377 return QV4::Encode::undefined();
3380bool QQuickJSContext2DPixelData::virtualPut(QV4::Managed *m, QV4::PropertyKey id,
const QV4::Value &value, QV4::Value *receiver)
3382 if (!id.isArrayIndex())
3383 return Object::virtualPut(m, id, value, receiver);
3387 QV4::Scope scope(v4);
3388 if (scope.hasException())
3391 uint index = id.asArrayIndex();
3392 QV4::Scoped<QQuickJSContext2DPixelData> r(scope,
static_cast<QQuickJSContext2DPixelData *>(m));
3394 const int v = value.toInt32();
3395 if (r && index <
static_cast<quint32>(r->d()->image->width() * r->d()->image->height() * 4) && v >= 0 && v <= 255) {
3396 const quint32 w = r->d()->image->width();
3397 const quint32 row = (index / 4) / w;
3398 const quint32 col = (index / 4) % w;
3400 QRgb* pixel =
reinterpret_cast<QRgb*>(r->d()->image->scanLine(row));
3402 switch (index % 4) {
3404 *pixel = qRgba(v, qGreen(*pixel), qBlue(*pixel), qAlpha(*pixel));
3407 *pixel = qRgba(qRed(*pixel), v, qBlue(*pixel), qAlpha(*pixel));
3410 *pixel = qRgba(qRed(*pixel), qGreen(*pixel), v, qAlpha(*pixel));
3413 *pixel = qRgba(qRed(*pixel), qGreen(*pixel), qBlue(*pixel), v);
3422
3423
3424
3425
3427
3428
3429
3430
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createImageData(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3444 QV4::Scope scope(b);
3445 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
3449 QV4::ScopedValue arg0(scope, argv[0]);
3450 QV4::Scoped<QQuickJSContext2DImageData> imgData(scope, arg0);
3452 QV4::Scoped<QQuickJSContext2DPixelData> pa(scope, imgData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3454 qreal w = pa->d()->image->width();
3455 qreal h = pa->d()->image->height();
3456 RETURN_RESULT(qt_create_image_data(w, h, scope.engine, QImage()));
3458 }
else if (arg0->isString()) {
3459 QImage image = r->d()->context()->createPixmap(QUrl(arg0->toQStringNoThrow()))->image();
3460 RETURN_RESULT(qt_create_image_data(image.width(), image.height(), scope.engine, std::move(image)));
3462 }
else if (argc == 2) {
3463 qreal w = argv[0].toNumber();
3464 qreal h = argv[1].toNumber();
3466 if (!qt_is_finite(w) || !qt_is_finite(h))
3467 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createImageData(): invalid arguments");
3470 RETURN_RESULT(qt_create_image_data(w, h, scope.engine, QImage()));
3472 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"createImageData(): invalid arguments");
3478
3479
3480
3481
3482
3483QV4::ReturnedValue
QQuickJSContext2DPrototype::method_getImageData(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3485 QV4::Scope scope(b);
3486 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
3490 qreal x = argv[0].toNumber();
3491 qreal y = argv[1].toNumber();
3492 qreal w = argv[2].toNumber();
3493 qreal h = argv[3].toNumber();
3494 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3495 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"getImageData(): Invalid arguments");
3497 if (w <= 0 || h <= 0)
3498 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"getImageData(): Invalid arguments");
3500 QImage image = r->d()->context()->canvas()->toImage(QRectF(x, y, w, h));
3501 RETURN_RESULT(qt_create_image_data(w, h, scope.engine, std::move(image)));
3503 RETURN_RESULT(QV4::Encode::null());
3507
3508
3509
3510
3511
3512
3513
3514
3515QV4::ReturnedValue
QQuickJSContext2DPrototype::method_putImageData(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3517 QV4::Scope scope(b);
3518 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
3523 QV4::ScopedValue arg0(scope, argv[0]);
3524 if (!arg0->isObject())
3525 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"Context2D::putImageData, the image data type mismatch");
3527 qreal dx = argv[1].toNumber();
3528 qreal dy = argv[2].toNumber();
3529 qreal w, h, dirtyX, dirtyY, dirtyWidth, dirtyHeight;
3531 if (!qt_is_finite(dx) || !qt_is_finite(dy))
3532 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"putImageData() : Invalid arguments");
3534 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, arg0);
3538 QV4::Scoped<QQuickJSContext2DPixelData> pixelArray(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3540 w = pixelArray->d()->image->width();
3541 h = pixelArray->d()->image->height();
3544 dirtyX = argv[3].toNumber();
3545 dirtyY = argv[4].toNumber();
3546 dirtyWidth = argv[5].toNumber();
3547 dirtyHeight = argv[6].toNumber();
3549 if (!qt_is_finite(dirtyX) || !qt_is_finite(dirtyY) || !qt_is_finite(dirtyWidth) || !qt_is_finite(dirtyHeight))
3550 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"putImageData() : Invalid arguments");
3553 if (dirtyWidth < 0) {
3554 dirtyX = dirtyX+dirtyWidth;
3555 dirtyWidth = -dirtyWidth;
3558 if (dirtyHeight < 0) {
3559 dirtyY = dirtyY+dirtyHeight;
3560 dirtyHeight = -dirtyHeight;
3564 dirtyWidth = dirtyWidth+dirtyX;
3569 dirtyHeight = dirtyHeight+dirtyY;
3573 if (dirtyX+dirtyWidth > w) {
3574 dirtyWidth = w - dirtyX;
3577 if (dirtyY+dirtyHeight > h) {
3578 dirtyHeight = h - dirtyY;
3581 if (dirtyWidth <=0 || dirtyHeight <= 0)
3590 QImage image = pixelArray->d()->image->copy(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
3591 r->d()->context()->buffer()->drawImage(image, QRectF(dirtyX, dirtyY, dirtyWidth, dirtyHeight), QRectF(dx, dy, dirtyWidth, dirtyHeight));
3594 RETURN_RESULT(*thisObject);
3598
3599
3600
3601
3602
3603
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619QV4::ReturnedValue
QQuickContext2DStyle::gradient_proto_addColorStop(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3621 QV4::Scope scope(b);
3622 QV4::Scoped<QQuickContext2DStyle> style(scope, thisObject->as<QQuickContext2DStyle>());
3624 THROW_GENERIC_ERROR(
"Not a CanvasGradient object");
3628 if (!style->d()->brush->gradient())
3629 THROW_GENERIC_ERROR(
"Not a valid CanvasGradient object, can't get the gradient information");
3630 QGradient gradient = *(style->d()->brush->gradient());
3631 qreal pos = argv[0].toNumber();
3634 if (argv[1].as<Object>()) {
3635 color = QV4::ExecutionEngine::toVariant(
3636 argv[1], QMetaType::fromType<QColor>()).value<QColor>();
3638 color = qt_color_from_string(argv[1]);
3640 if (pos < 0.0 || pos > 1.0 || !qt_is_finite(pos)) {
3641 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"CanvasGradient: parameter offset out of range");
3644 if (color.isValid()) {
3645 gradient.setColorAt(pos, color);
3647 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"CanvasGradient: parameter color is not a valid color string");
3649 *style->d()->brush = gradient;
3652 return thisObject->asReturnedValue();
3657 if (!state.invertibleCTM)
3660 if (!qt_is_finite(x) || !qt_is_finite(y))
3663 QTransform newTransform = state.matrix;
3664 newTransform.scale(x, y);
3666 if (!newTransform.isInvertible()) {
3667 state.invertibleCTM =
false;
3671 state.matrix = newTransform;
3672 buffer()->updateMatrix(state.matrix);
3673 m_path = QTransform().scale(1.0 / x, 1.0 / y).map(m_path);
3678 if (!state.invertibleCTM)
3681 if (!qt_is_finite(angle))
3684 QTransform newTransform =state.matrix;
3685 newTransform.rotate(qRadiansToDegrees(angle));
3687 if (!newTransform.isInvertible()) {
3688 state.invertibleCTM =
false;
3692 state.matrix = newTransform;
3693 buffer()->updateMatrix(state.matrix);
3694 m_path = QTransform().rotate(-qRadiansToDegrees(angle)).map(m_path);
3699 if (!state.invertibleCTM)
3702 if (!qt_is_finite(h) || !qt_is_finite(v))
3705 QTransform newTransform = state.matrix;
3706 newTransform.shear(h, v);
3708 if (!newTransform.isInvertible()) {
3709 state.invertibleCTM =
false;
3713 state.matrix = newTransform;
3714 buffer()->updateMatrix(state.matrix);
3715 m_path = QTransform().shear(-h, -v).map(m_path);
3720 if (!state.invertibleCTM)
3723 if (!qt_is_finite(x) || !qt_is_finite(y))
3726 QTransform newTransform = state.matrix;
3727 newTransform.translate(x, y);
3729 if (!newTransform.isInvertible()) {
3730 state.invertibleCTM =
false;
3734 state.matrix = newTransform;
3735 buffer()->updateMatrix(state.matrix);
3736 m_path = QTransform().translate(-x, -y).map(m_path);
3741 if (!state.invertibleCTM)
3744 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))
3747 QTransform transform(a, b, c, d, e, f);
3748 QTransform newTransform = state.matrix * transform;
3750 if (!newTransform.isInvertible()) {
3751 state.invertibleCTM =
false;
3754 state.matrix = newTransform;
3755 buffer()->updateMatrix(state.matrix);
3756 m_path = transform.inverted().map(m_path);
3761 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))
3764 QTransform ctm = state.matrix;
3765 if (!ctm.isInvertible())
3768 state.matrix = ctm.inverted() * state.matrix;
3769 m_path = ctm.map(m_path);
3770 state.invertibleCTM =
true;
3771 transform(a, b, c, d, e, f);
3776 if (!state.invertibleCTM)
3779 if (!m_path.elementCount())
3782 m_path.setFillRule(state.fillRule);
3788 if (!state.invertibleCTM)
3791 QPainterPath clipPath = m_path;
3792 clipPath.closeSubpath();
3794 state.clipPath = clipPath.intersected(state.clipPath);
3797 state.clipPath = clipPath;
3799 buffer()->clip(state.clip, state.clipPath);
3804 if (!state.invertibleCTM)
3807 if (!m_path.elementCount())
3815 if (!state.invertibleCTM)
3818 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3821 buffer()->fillRect(QRectF(x, y, w, h));
3826 if (!state.invertibleCTM)
3829 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3832 buffer()->strokeRect(QRectF(x, y, w, h));
3837 if (!state.invertibleCTM)
3840 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3843 buffer()->clearRect(QRectF(x, y, w, h));
3848 if (!state.invertibleCTM)
3851 if (!qt_is_finite(x) || !qt_is_finite(y))
3854 QPainterPath textPath = createTextGlyphs(x, y, text);
3864 if (!m_path.elementCount())
3866 m_path = QPainterPath();
3871 if (!m_path.elementCount())
3874 QRectF boundRect = m_path.boundingRect();
3875 if (boundRect.width() || boundRect.height())
3876 m_path.closeSubpath();
3883 if (!state.invertibleCTM)
3887 m_path.moveTo(QPointF(x, y));
3892 if (!state.invertibleCTM)
3897 if (!m_path.elementCount())
3899 else if (m_path.currentPosition() != pt)
3906 if (!state.invertibleCTM)
3909 if (!m_path.elementCount())
3910 m_path.moveTo(QPointF(cpx, cpy));
3913 if (m_path.currentPosition() != pt)
3914 m_path.quadTo(QPointF(cpx, cpy), pt);
3918 qreal cp2x, qreal cp2y,
3921 if (!state.invertibleCTM)
3924 if (!m_path.elementCount())
3925 m_path.moveTo(QPointF(cp1x, cp1y));
3928 if (m_path.currentPosition() != pt)
3929 m_path.cubicTo(QPointF(cp1x, cp1y), QPointF(cp2x, cp2y), pt);
3934 QPointF p0(m_path.currentPosition());
3936 QPointF p1p0((p0.x() - p1.x()), (p0.y() - p1.y()));
3937 QPointF p1p2((p2.x() - p1.x()), (p2.y() - p1.y()));
3938 qreal p1p0_length =
std::hypot(p1p0.x(), p1p0.y());
3939 qreal p1p2_length =
std::hypot(p1p2.x(), p1p2.y());
3941 qreal cos_phi = QPointF::dotProduct(p1p0, p1p2) / (p1p0_length * p1p2_length);
3946 if (qFuzzyCompare(
std::abs(cos_phi), qreal(1.0))) {
3951 qreal tangent = radius /
std::tan(
std::acos(cos_phi) / 2);
3952 qreal factor_p1p0 = tangent / p1p0_length;
3953 QPointF t_p1p0((p1.x() + factor_p1p0 * p1p0.x()), (p1.y() + factor_p1p0 * p1p0.y()));
3955 QPointF orth_p1p0(p1p0.y(), -p1p0.x());
3956 qreal orth_p1p0_length =
std::hypot(orth_p1p0.x(), orth_p1p0.y());
3957 qreal factor_ra = radius / orth_p1p0_length;
3960 qreal cos_alpha = QPointF::dotProduct(orth_p1p0, p1p2) / (orth_p1p0_length * p1p2_length);
3961 if (cos_alpha < 0.f)
3962 orth_p1p0 = QPointF(-orth_p1p0.x(), -orth_p1p0.y());
3964 QPointF p((t_p1p0.x() + factor_ra * orth_p1p0.x()), (t_p1p0.y() + factor_ra * orth_p1p0.y()));
3967 orth_p1p0 = QPointF(-orth_p1p0.x(), -orth_p1p0.y());
3968 qreal sa =
std::atan2(orth_p1p0.y(), orth_p1p0.x());
3971 bool anticlockwise =
false;
3973 qreal factor_p1p2 = tangent / p1p2_length;
3974 QPointF t_p1p2((p1.x() + factor_p1p2 * p1p2.x()), (p1.y() + factor_p1p2 * p1p2.y()));
3975 QPointF orth_p1p2((t_p1p2.x() - p.x()), (t_p1p2.y() - p.y()));
3976 qreal ea =
std::atan2(orth_p1p2.y(), orth_p1p2.x());
3977 if ((sa > ea) && ((sa - ea) <
M_PI))
3978 anticlockwise =
true;
3979 if ((sa < ea) && ((ea - sa) >
M_PI))
3980 anticlockwise =
true;
3982 arc(p.x(), p.y(), radius, sa, ea, anticlockwise);
3989 if (!state.invertibleCTM)
3992 if (!qt_is_finite(x1) || !qt_is_finite(y1) || !qt_is_finite(x2) || !qt_is_finite(y2) || !qt_is_finite(radius))
3996 QPointF end(x2, y2);
3998 if (!m_path.elementCount())
4000 else if (st == m_path.currentPosition() || st == end || !radius)
4003 addArcTo(st, end, radius);
4008 if (!state.invertibleCTM)
4010 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
4014 m_path.moveTo(x, y);
4017 m_path.addRect(x, y, w, h);
4024 if (!state.invertibleCTM)
4027 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))
4031 m_path.moveTo(x, y);
4034 m_path.addRoundedRect(QRectF(x, y, w, h), xr, yr, Qt::AbsoluteSize);
4040 if (!state.invertibleCTM)
4043 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
4047 m_path.moveTo(x, y);
4051 m_path.addEllipse(x, y, w, h);
4056 if (!state.invertibleCTM)
4060 path.addText(x, y, state.font, str);
4061 m_path.addPath(path);
4066 if (!state.invertibleCTM)
4069 if (!qt_is_finite(xc) || !qt_is_finite(yc) || !qt_is_finite(sar) || !qt_is_finite(ear) || !qt_is_finite(radius))
4083 antiClockWise = !antiClockWise;
4086 float sa = qRadiansToDegrees(sar);
4087 float ea = qRadiansToDegrees(ear);
4091 double xs = xc - radius;
4092 double ys = yc - radius;
4093 double width = radius*2;
4094 double height = radius*2;
4095 if ((!antiClockWise && (ea - sa >= 360)) || (antiClockWise && (sa - ea >= 360)))
4101 if (!antiClockWise && (ea < sa)) {
4103 }
else if (antiClockWise && (sa < ea)) {
4108 if (!(qFuzzyCompare(span + (ea - sa) + 1, 1) &&
4109 qFuzzyCompare(qAbs(span), 360))) {
4115 if (!m_path.elementCount())
4116 m_path.arcMoveTo(xs, ys, width, height, sa);
4118 m_path.lineTo(xc, yc);
4122 m_path.arcTo(xs, ys, width, height, sa, span);
4125int baseLineOffset(QQuickContext2D::TextBaseLineType value,
const QFontMetrics &metrics)
4129 case QQuickContext2D::Top:
4130 case QQuickContext2D::Hanging:
4132 case QQuickContext2D::Middle:
4133 offset = (metrics.ascent() >> 1) + metrics.height() - metrics.ascent();
4135 case QQuickContext2D::Alphabetic:
4136 offset = metrics.ascent();
4138 case QQuickContext2D::Bottom:
4139 offset = metrics.height();
4148 if (value == QQuickContext2D::Start)
4149 value = QGuiApplication::layoutDirection() == Qt::LeftToRight ? QQuickContext2D::Left : QQuickContext2D::Right;
4150 else if (value == QQuickContext2D::End)
4151 value = QGuiApplication::layoutDirection() == Qt::LeftToRight ? QQuickContext2D::Right: QQuickContext2D::Left;
4154 offset = metrics.horizontalAdvance(text) / 2;
4157 offset = metrics.horizontalAdvance(text);
4168 m_grabbedImage = grab;
4172QQmlRefPointer<QQuickCanvasPixmap>
QQuickContext2D::createPixmap(
const QUrl& url, QSizeF sourceSize)
4174 return m_canvas->loadedPixmap(url, sourceSize);
4179 const QFontMetrics metrics(state.font);
4180 int yoffset = baseLineOffset(
static_cast<QQuickContext2D::TextBaseLineType>(state.textBaseline), metrics);
4181 int xoffset = textAlignOffset(
static_cast<QQuickContext2D::TextAlignType>(state.textAlign), metrics, text);
4183 QPainterPath textPath;
4185 textPath.addText(x - xoffset, y - yoffset+metrics.ascent(), state.font, text);
4190static inline bool areCollinear(
const QPointF& a,
const QPointF& b,
const QPointF& c)
4193 return qFuzzyCompare((c.y() - b.y()) * (a.x() - b.x()), (a.y() - b.y()) * (c.x() - b.x()));
4198 return (p >= a && p <= b) || (p >= b && p <= a);
4203 if (!state.invertibleCTM)
4206 if (!m_path.elementCount())
4209 if (!qt_is_finite(x) || !qt_is_finite(y))
4212 QPointF point(x, y);
4213 QTransform ctm = state.matrix;
4214 QPointF p = ctm.inverted().map(point);
4215 if (!qt_is_finite(p.x()) || !qt_is_finite(p.y()))
4218 const_cast<
QQuickContext2D *>(
this)->m_path.setFillRule(state.fillRule);
4220 bool contains = m_path.contains(p);
4224 QPolygonF border = m_path.toFillPolygon();
4226 QPointF p1 = border.at(0);
4229 for (
int i = 1; i < border.size(); ++i) {
4231 if (areCollinear(p, p1, p2)
4234 && (qAbs(p2.x() - p1.x()) > qAbs(p2.y() - p1.y()) ?
4235 withinRange(p.x(), p1.x(), p2.x()) :
4236 withinRange(p.y(), p1.y(), p2.y()))) {
4269 return m_v4value.value();
4274 return QStringList() << QStringLiteral(
"2d");
4281 m_canvas = canvasItem;
4282 m_renderTarget = canvasItem->renderTarget();
4283 m_renderStrategy = canvasItem->renderStrategy();
4286 if (m_renderTarget == QQuickCanvasItem::FramebufferObject
4287 && m_renderStrategy == QQuickCanvasItem::Threaded
4288 && !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL)) {
4289 m_renderTarget = QQuickCanvasItem::Image;
4295 if (m_renderTarget == QQuickCanvasItem::FramebufferObject)
4296 m_renderTarget = QQuickCanvasItem::Image;
4298 m_texture =
new QQuickContext2DImageTexture;
4301 m_texture->setCanvasWindow(canvasItem->canvasWindow().toRect());
4302 m_texture->setTileSize(canvasItem->tileSize());
4303 m_texture->setCanvasSize(canvasItem->canvasSize().toSize());
4304 m_texture->setSmooth(canvasItem->smooth());
4305 m_texture->setAntialiasing(canvasItem->antialiasing());
4306 m_texture->setOnCustomThread(m_renderStrategy == QQuickCanvasItem::Threaded);
4307 m_thread = QThread::currentThread();
4309 QThread *renderThread = m_thread;
4310 if (m_renderStrategy == QQuickCanvasItem::Threaded)
4312 if (renderThread && renderThread != QThread::currentThread())
4314 connect(
m_texture, SIGNAL(textureChanged()), SIGNAL(textureChanged()));
4319void QQuickContext2D::
prepare(
const QSize& canvasSize,
const QSize& tileSize,
const QRect& canvasWindow,
const QRect& dirtyRect,
bool smooth,
bool antialiasing)
4321 if (m_texture->thread() == QThread::currentThread()) {
4322 m_texture->canvasChanged(canvasSize, tileSize, canvasWindow, dirtyRect, smooth, antialiasing);
4324 QEvent *e =
new QQuickContext2DTexture::CanvasChangeEvent(canvasSize,
4330 QCoreApplication::postEvent(m_texture, e);
4337 if (m_texture->thread() == QThread::currentThread())
4340 QCoreApplication::postEvent(m_texture,
new QQuickContext2DTexture::PaintEvent(m_buffer));
4352 if (m_texture->thread() == QThread::currentThread()) {
4355 }
else if (m_renderStrategy == QQuickCanvasItem::Cooperative) {
4356 qWarning() <<
"Pixel readback is not supported in Cooperative mode, please try Threaded or Immediate mode";
4360 QCoreApplication::postEvent(m_texture,
new QEvent(QEvent::Type(QEvent::User + 10)));
4361 QMetaObject::invokeMethod(m_texture,
4363 Qt::BlockingQueuedConnection,
4364 Q_ARG(QRectF, bounds));
4366 QImage img = m_grabbedImage;
4367 m_grabbedImage = QImage();
4375 QV4::Scope scope(v4);
4377 QV4::ScopedObject proto(scope, QQuickJSContext2DPrototype::create(v4));
4378 proto->defineAccessorProperty(QStringLiteral(
"strokeStyle"), QQuickJSContext2D::method_get_strokeStyle, QQuickJSContext2D::method_set_strokeStyle);
4379 proto->defineAccessorProperty(QStringLiteral(
"font"), QQuickJSContext2D::method_get_font, QQuickJSContext2D::method_set_font);
4380 proto->defineAccessorProperty(QStringLiteral(
"fillRule"), QQuickJSContext2D::method_get_fillRule, QQuickJSContext2D::method_set_fillRule);
4381 proto->defineAccessorProperty(QStringLiteral(
"globalAlpha"), QQuickJSContext2D::method_get_globalAlpha, QQuickJSContext2D::method_set_globalAlpha);
4382 proto->defineAccessorProperty(QStringLiteral(
"lineCap"), QQuickJSContext2D::method_get_lineCap, QQuickJSContext2D::method_set_lineCap);
4383 proto->defineAccessorProperty(QStringLiteral(
"shadowOffsetX"), QQuickJSContext2D::method_get_shadowOffsetX, QQuickJSContext2D::method_set_shadowOffsetX);
4384 proto->defineAccessorProperty(QStringLiteral(
"shadowOffsetY"), QQuickJSContext2D::method_get_shadowOffsetY, QQuickJSContext2D::method_set_shadowOffsetY);
4385 proto->defineAccessorProperty(QStringLiteral(
"globalCompositeOperation"), QQuickJSContext2D::method_get_globalCompositeOperation, QQuickJSContext2D::method_set_globalCompositeOperation);
4386 proto->defineAccessorProperty(QStringLiteral(
"miterLimit"), QQuickJSContext2D::method_get_miterLimit, QQuickJSContext2D::method_set_miterLimit);
4387 proto->defineAccessorProperty(QStringLiteral(
"fillStyle"), QQuickJSContext2D::method_get_fillStyle, QQuickJSContext2D::method_set_fillStyle);
4388 proto->defineAccessorProperty(QStringLiteral(
"shadowColor"), QQuickJSContext2D::method_get_shadowColor, QQuickJSContext2D::method_set_shadowColor);
4389 proto->defineAccessorProperty(QStringLiteral(
"textBaseline"), QQuickJSContext2D::method_get_textBaseline, QQuickJSContext2D::method_set_textBaseline);
4390#if QT_CONFIG(quick_path)
4391 proto->defineAccessorProperty(QStringLiteral(
"path"), QQuickJSContext2D::method_get_path, QQuickJSContext2D::method_set_path);
4393 proto->defineAccessorProperty(QStringLiteral(
"lineJoin"), QQuickJSContext2D::method_get_lineJoin, QQuickJSContext2D::method_set_lineJoin);
4394 proto->defineAccessorProperty(QStringLiteral(
"lineWidth"), QQuickJSContext2D::method_get_lineWidth, QQuickJSContext2D::method_set_lineWidth);
4395 proto->defineAccessorProperty(QStringLiteral(
"textAlign"), QQuickJSContext2D::method_get_textAlign, QQuickJSContext2D::method_set_textAlign);
4396 proto->defineAccessorProperty(QStringLiteral(
"shadowBlur"), QQuickJSContext2D::method_get_shadowBlur, QQuickJSContext2D::method_set_shadowBlur);
4397 proto->defineAccessorProperty(QStringLiteral(
"lineDashOffset"), QQuickJSContext2D::method_get_lineDashOffset, QQuickJSContext2D::method_set_lineDashOffset);
4398 contextPrototype = proto;
4400 proto = scope.engine->newObject();
4401 proto->defineDefaultProperty(QStringLiteral(
"addColorStop"), QQuickContext2DStyle::gradient_proto_addColorStop, 0);
4402 gradientProto = proto;
4404 proto = scope.engine->newObject();
4405 proto->defineAccessorProperty(scope.engine->id_length(), QQuickJSContext2DPixelData::proto_get_length,
nullptr);
4406 pixelArrayProto = proto;
4415 if (m_stateStack.isEmpty())
4420 if (state.matrix != newState.matrix)
4421 buffer()->updateMatrix(newState.matrix);
4423 if (newState.globalAlpha != state.globalAlpha)
4424 buffer()->setGlobalAlpha(newState.globalAlpha);
4426 if (newState.globalCompositeOperation != state.globalCompositeOperation)
4427 buffer()->setGlobalCompositeOperation(newState.globalCompositeOperation);
4429 if (newState.fillStyle != state.fillStyle)
4430 buffer()->setFillStyle(newState.fillStyle);
4432 if (newState.strokeStyle != state.strokeStyle)
4433 buffer()->setStrokeStyle(newState.strokeStyle);
4435 if (newState.lineWidth != state.lineWidth)
4436 buffer()->setLineWidth(newState.lineWidth);
4438 if (newState.lineCap != state.lineCap)
4439 buffer()->setLineCap(newState.lineCap);
4441 if (newState.lineJoin != state.lineJoin)
4442 buffer()->setLineJoin(newState.lineJoin);
4444 if (newState.miterLimit != state.miterLimit)
4445 buffer()->setMiterLimit(newState.miterLimit);
4447 if (newState.clip != state.clip || newState.clipPath != state.clipPath)
4450 if (newState.shadowBlur != state.shadowBlur)
4451 buffer()->setShadowBlur(newState.shadowBlur);
4453 if (newState.shadowColor != state.shadowColor)
4454 buffer()->setShadowColor(newState.shadowColor);
4456 if (newState.shadowOffsetX != state.shadowOffsetX)
4457 buffer()->setShadowOffsetX(newState.shadowOffsetX);
4459 if (newState.shadowOffsetY != state.shadowOffsetY)
4460 buffer()->setShadowOffsetY(newState.shadowOffsetY);
4462 if (newState.lineDash != state.lineDash)
4463 buffer()->setLineDash(newState.lineDash);
4465 m_path = state.matrix.map(m_path);
4467 m_path = state.matrix.inverted().map(m_path);
4471 m_stateStack.push(state);
4478 m_path = QPainterPath();
4480 newState.clipPath.setFillRule(Qt::WindingFill);
4482 m_stateStack.clear();
4483 m_stateStack.push(newState);
4485 m_buffer->clearRect(QRectF(0, 0, m_canvas->width(), m_canvas->height()));
4502 QV4::Scope scope(engine);
4503 QV4::Scoped<QQuickJSContext2D> wrapper(scope, engine->memoryManager->allocate<QQuickJSContext2D>());
4504 QV4::ScopedObject p(scope, ed->contextPrototype.value());
4505 wrapper->setPrototypeOf(p);
4506 wrapper->d()->setContext(
this);
4507 m_v4value = wrapper;
4513#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)
QImage qt_image_convolute_filter(const QImage &src, const QList< qreal > &weights, int radius=0)
DEFINE_OBJECT_VTABLE(QQuickContext2DStyle)
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 QString makeColorString(QColor color)
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 CanvasPixelArray QtQuick::CanvasImageData::data Holds the one-dimensional array containi...
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 bool 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 var QtQuick::Context2D::measureText(text)
static QV4::ReturnedValue method_moveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D 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 Context2D 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 void 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 Context2D 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 void QtQuick::Context2D::drawImage(variant image, real dx, real dy) Draws the given image ...
static QV4::ReturnedValue method_scale(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D 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 Context2D QtQuick::Context2D::stroke()
static QV4::ReturnedValue method_closePath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D QtQuick::Context2D::closePath() Closes the current subpath by drawing a line to ...
static QV4::ReturnedValue method_strokeRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D 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 Context2D QtQuick::Context2D::transform(real a, real b, real c, real d,...
static QV4::ReturnedValue method_translate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D 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 Context2D 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 Context2D QtQuick::Context2D::resetTransform()
static QV4::ReturnedValue method_createRadialGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod CanvasGradient QtQuick::Context2D::createRadialGradient(real x0, real y0,...
static QV4::ReturnedValue method_clip(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D QtQuick::Context2D::clip()
static QV4::ReturnedValue method_createLinearGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod CanvasGradient QtQuick::Context2D::createLinearGradient(real x0, real y0,...
static QV4::ReturnedValue method_reset(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D QtQuick::Context2D::reset() Resets the context state and properties to the defau...
static QV4::ReturnedValue method_fillText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D 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 Context2D 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 Context2D 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 Context2D 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 Context2D 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 Context2D 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 CanvasGradient QtQuick::Context2D::createConicalGradient(real x, real y,...
static QV4::ReturnedValue method_strokeText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D 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 Context2D QtQuick::Context2D::restore() Pops the top state on the stack,...
static QV4::ReturnedValue method_rect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D 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 Context2D QtQuick::Context2D::beginPath()
static QV4::ReturnedValue method_rotate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D QtQuick::Context2D::rotate(real angle) Rotate the canvas around the current orig...
static QV4::ReturnedValue method_fillRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D 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 Context2D 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 Context2D 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 Context2D QtQuick::Context2D::roundedRect(real x, real y, real w, real h,...
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 void 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 Context2D 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 Context2D 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)